Интенсив по разработке мобильного приложения 1С, для внутри корпоративного использования. Разработка обмена, динамического интерфейса, авторизации, XDTO. В процессе изучения вы создадите мобильное приложение 1С для B2B с нуля до 100%.
-10%
9 990 руб.
8 991 руб.
Разработай красивое мобильное приложение 1С с помощью HTML и CSS
TurboConf повышает эффективность работы в Конфигураторе 1С и помогает программисту автоматизировать свои задачи.
Интенсив по разработке чат бота ВКонтакте. Используя API ВКонтакте создавать чат бот ВКонтакте из 1С. Получить список пользователей группы ВКонтакте и разослать им сообщения.
Закрой все вопросы по XDTO за одно занятие!
ПараметрыСтроки = ОбщегоНазначения.СтрокаТаблицыЗначенийВСтруктуру(ТаблицаПоказателей[0]);
ПараметрыСтроки = ОбщегоНазначения.СтрокаТаблицыЗначенийВСтруктуру(ТаблицаПоказателей[0]);
ВидыРасчета = Новый Массив;
Для Каждого СтрокаИсточника Из ТаблицаВычислений Цикл
ВидыРасчета.Добавить(СтрокаИсточника.ВидНачисления);
КонецЦикла;
ВидыРасчетаИнфо = ОбщегоНазначения.ЗначенияРеквизитовОбъектов(ВидыРасчета, "УчетВремениВЧасах,КатегорияНачисленияИлиНеоплаченногоВремени,ТребуетсяРасчетБазы");
ВидыРасчета = Новый Массив;
Для Каждого СтрокаИсточника Из ТаблицаВычислений Цикл
ВидыРасчета.Добавить(СтрокаИсточника.ВидНачисления);
КонецЦикла;
ВидыРасчетаИнфо = ОбщегоНазначения.ЗначенияРеквизитовОбъектов(ВидыРасчета, "УчетВремениВЧасах,КатегорияНачисленияИлиНеоплаченногоВремени,ТребуетсяРасчетБазы");
В старых версиях конфигураций можно получить сообщение о том, что, например, СтрРазделить не найден. Тогда в качестве альтернативы стоит использовать ОбщийМодуль → СтроковыеФункцииКлиентСервер, где собраны необходимые функции по работе со строкой. Например...
&НаКлиенте
Процедура СформироватьCsvФайл(Команда)
ПутьККаталогу = ОткрытьДиалогВыбораФайла();
Текст = ВыгрузитьВCSV(ПутьККаталогу.ПолноеИмяФайла);
Кодировка = КодировкаТекста.ANSI;
ТекстовыйФайлЗапись = Новый ЗаписьТекста(ПутьККаталогу.ПолноеИмяФайла,Кодировка);
ТекстовыйФайлЗапись.ЗаписатьСтроку(Текст);
ТекстовыйФайлЗапись.Закрыть();
КонецПроцедуры
&НаКлиенте
Функция ОткрытьДиалогВыбораФайла(НачальныйКаталог = Неопределено, МножественныйВыбор = Ложь, Фильтр = Неопределено) экспорт
СтандартнаяОбработка = Ложь;
ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
ДиалогОткрытияФайла.Расширение = "csv";
Фильтр = "csv|*.csv";
ДиалогОткрытияФайла.Фильтр = Фильтр;
ДиалогОткрытияФайла.Каталог = НачальныйКаталог;
ДиалогОткрытияФайла.Заголовок = "Выберите каталог...";
ДиалогОткрытияФайла.МножественныйВыбор = Ложь;
ДиалогОткрытияФайла.ПроверятьСуществованиеФайла = Истина;
ДиалогОткрытияФайла.ПредварительныйПросмотр = Истина;
Если Не ДиалогОткрытияФайла.Выбрать() Тогда
Возврат Неопределено;
КонецЕсли;
Возврат ДиалогОткрытияФайла;
КонецФункции
Функция ВыгрузитьВCSV(имяФайлаCSV);
Текст = СоздатьДанныеCSV(ТаблицаДокументов,Разделитель);
Возврат Текст;
КонецФункции
Функция СоздатьДанныеCSV(ТаблицаДокументов, Разделитель)
Текст = "";
Для Каждого Запись из ТаблицаДокументов Цикл
Если Текст = "" тогда
Текст = СоздатьЗаголовкиCSV(ТаблицаДокументов, Разделитель) + Символы.ПС;
КонецЕсли;
Текст = Текст + Запись.snils + Разделитель + Запись.surname
+ Разделитель + Запись.name + Разделитель + Запись.patronymic + Разделитель
+ Запись.oid + Разделитель + Запись.compaignId + Разделитель + Формат(Запись.dateOfBirth, "ДЛФ=Д") + Разделитель + Запись.citizenship + Разделитель
+ Запись.specialty + Разделитель + Запись.financingType + Разделитель + Запись.applicationDate + Разделитель + Запись.targetReception
+ Разделитель + Запись.testResultType + Разделитель + Запись.testResultOrganization + Разделитель + Запись.testResultYear + Символы.ПС;
КонецЦикла;
Возврат Текст;
КонецФункции
// Создаем строку загоовков для CSV-файла
Функция СоздатьЗаголовкиCSV(ТаблицаДокументов, Разделитель)
НоваяТаблица = ТаблицаДокументов.Выгрузить();
КолонкиТЗ = НоваяТаблица.Колонки;
Для каждого Колонка Из КолонкиТЗ Цикл
СтрКолонки = "" + СтрКолонки + Колонка.Имя + Разделитель;
КонецЦикла;
Возврат СтрКолонки;
КонецФункции
&НаКлиенте
Процедура СформироватьCsvФайл(Команда)
ПутьККаталогу = ОткрытьДиалогВыбораФайла();
Текст = ВыгрузитьВCSV(ПутьККаталогу.ПолноеИмяФайла);
Кодировка = КодировкаТекста.ANSI;
ТекстовыйФайлЗапись = Новый ЗаписьТекста(ПутьККаталогу.ПолноеИмяФайла,Кодировка);
ТекстовыйФайлЗапись.ЗаписатьСтроку(Текст);
ТекстовыйФайлЗапись.Закрыть();
КонецПроцедуры
&НаКлиенте
Функция ОткрытьДиалогВыбораФайла(НачальныйКаталог = Неопределено, МножественныйВыбор = Ложь, Фильтр = Неопределено) экспорт
СтандартнаяОбработка = Ложь;
ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
ДиалогОткрытияФайла.Расширение = "csv";
Фильтр = "csv|*.csv";
ДиалогОткрытияФайла.Фильтр = Фильтр;
ДиалогОткрытияФайла.Каталог = НачальныйКаталог;
ДиалогОткрытияФайла.Заголовок = "Выберите каталог...";
ДиалогОткрытияФайла.МножественныйВыбор = Ложь;
ДиалогОткрытияФайла.ПроверятьСуществованиеФайла = Истина;
ДиалогОткрытияФайла.ПредварительныйПросмотр = Истина;
Если Не ДиалогОткрытияФайла.Выбрать() Тогда
Возврат Неопределено;
КонецЕсли;
Возврат ДиалогОткрытияФайла;
КонецФункции
Функция ВыгрузитьВCSV(имяФайлаCSV);
Текст = СоздатьДанныеCSV(ТаблицаДокументов,Разделитель);
Возврат Текст;
КонецФункции
Функция СоздатьДанныеCSV(ТаблицаДокументов, Разделитель)
Текст = "";
Для Каждого Запись из ТаблицаДокументов Цикл
Если Текст = "" тогда
Текст = СоздатьЗаголовкиCSV(ТаблицаДокументов, Разделитель) + Символы.ПС;
КонецЕсли;
Текст = Текст + Запись.snils + Разделитель + Запись.surname
+ Разделитель + Запись.name + Разделитель + Запись.patronymic + Разделитель
+ Запись.oid + Разделитель + Запись.compaignId + Разделитель + Формат(Запись.dateOfBirth, "ДЛФ=Д") + Разделитель + Запись.citizenship + Разделитель
+ Запись.specialty + Разделитель + Запись.financingType + Разделитель + Запись.applicationDate + Разделитель + Запись.targetReception
+ Разделитель + Запись.testResultType + Разделитель + Запись.testResultOrganization + Разделитель + Запись.testResultYear + Символы.ПС;
КонецЦикла;
Возврат Текст;
КонецФункции
// Создаем строку загоовков для CSV-файла
Функция СоздатьЗаголовкиCSV(ТаблицаДокументов, Разделитель)
НоваяТаблица = ТаблицаДокументов.Выгрузить();
КолонкиТЗ = НоваяТаблица.Колонки;
Для каждого Колонка Из КолонкиТЗ Цикл
СтрКолонки = "" + СтрКолонки + Колонка.Имя + Разделитель;
КонецЦикла;
Возврат СтрКолонки;
КонецФункции
ТЗ_рез = РеквизитФормыВЗначение("ТЗДокументы");
МассивРеквизитов = Новый Массив;
//Удалим ранее созданные колонки в ТЗДокументы
Для Каждого Колонка Из ТЗ_рез.Колонки Цикл
МассивРеквизитов.Добавить("ТЗДокументы." + Колонка.Имя);
КонецЦикла;
ИзменитьРеквизиты(,МассивРеквизитов);
//Удалим отображение таблицы на форме и создадим новую
ЭлементТаблица = Элементы.Найти("ТЗДокументы");
Если ЭлементТаблица <> Неопределено Тогда
Элементы.Удалить(ЭлементТаблица);
КонецЕсли;
ЭлементТаблица=Элементы.Добавить("ТЗДокументы",Тип("ТаблицаФормы"));
ЭлементТаблица.ПутьКДанным = "ТЗДокументы";
ЭлементТаблица.Отображение = ОтображениеТаблицы.Список;
ТЗ_рез = Данные;
//Создадим реквизиты ТЗ
МассивРеквизитов.Очистить();
Для Каждого Колонка ИЗ ТЗ_рез.Колонки Цикл
МассивТипов = Новый Массив;
МассивТипов.Добавить(Колонка.ТипЗначения);
НоваяКолонка = Новый РеквизитФормы(Колонка.Имя, Новый ОписаниеТипов(МассивТипов), "ТЗДокументы");
МассивРеквизитов.Добавить(НоваяКолонка);
КонецЦикла;
ИзменитьРеквизиты(МассивРеквизитов);
ЗначениеВРеквизитФормы(ТЗ_рез, "ТЗДокументы");
//Создаем элементы на форме для отображения колонок
ЭлементТЗ = Элементы.ТЗДокументы;
Для Каждого Колонка ИЗ ТЗ_рез.Колонки Цикл
НовыйЭлементФормы = Элементы.Добавить("ТЗДокументы"+Колонка.Имя, Тип("ПолеФормы"), ЭлементТЗ);
НовыйЭлементФормы.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлементФормы.ПутьКДанным = "ТЗДокументы." + Колонка.Имя;
КонецЦикла;
ТЗ_рез = РеквизитФормыВЗначение("ТЗДокументы");
МассивРеквизитов = Новый Массив;
//Удалим ранее созданные колонки в ТЗДокументы
Для Каждого Колонка Из ТЗ_рез.Колонки Цикл
МассивРеквизитов.Добавить("ТЗДокументы." + Колонка.Имя);
КонецЦикла;
ИзменитьРеквизиты(,МассивРеквизитов);
//Удалим отображение таблицы на форме и создадим новую
ЭлементТаблица = Элементы.Найти("ТЗДокументы");
Если ЭлементТаблица <> Неопределено Тогда
Элементы.Удалить(ЭлементТаблица);
КонецЕсли;
ЭлементТаблица=Элементы.Добавить("ТЗДокументы",Тип("ТаблицаФормы"));
ЭлементТаблица.ПутьКДанным = "ТЗДокументы";
ЭлементТаблица.Отображение = ОтображениеТаблицы.Список;
ТЗ_рез = Данные;
//Создадим реквизиты ТЗ
МассивРеквизитов.Очистить();
Для Каждого Колонка ИЗ ТЗ_рез.Колонки Цикл
МассивТипов = Новый Массив;
МассивТипов.Добавить(Колонка.ТипЗначения);
НоваяКолонка = Новый РеквизитФормы(Колонка.Имя, Новый ОписаниеТипов(МассивТипов), "ТЗДокументы");
МассивРеквизитов.Добавить(НоваяКолонка);
КонецЦикла;
ИзменитьРеквизиты(МассивРеквизитов);
ЗначениеВРеквизитФормы(ТЗ_рез, "ТЗДокументы");
//Создаем элементы на форме для отображения колонок
ЭлементТЗ = Элементы.ТЗДокументы;
Для Каждого Колонка ИЗ ТЗ_рез.Колонки Цикл
НовыйЭлементФормы = Элементы.Добавить("ТЗДокументы"+Колонка.Имя, Тип("ПолеФормы"), ЭлементТЗ);
НовыйЭлементФормы.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлементФормы.ПутьКДанным = "ТЗДокументы." + Колонка.Имя;
КонецЦикла;
СхемаКомпоновкиДанных = ПолучитьМакет("МакетСКД");
АдресСхемыКомпоновкиДанных = ПоместитьВоВременноеХранилище(СхемаКомпоновкиДанных, Новый УникальныйИдентификатор);
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСхемыКомпоновкиДанных);
КомпоновщикНастроек.Инициализировать(ИсточникДоступныхНастроек);
КомпоновщикНастроек.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию);
СхемаКомпоновкиДанных = ПолучитьМакет("МакетСКД");
АдресСхемыКомпоновкиДанных = ПоместитьВоВременноеХранилище(СхемаКомпоновкиДанных, Новый УникальныйИдентификатор);
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСхемыКомпоновкиДанных);
КомпоновщикНастроек.Инициализировать(ИсточникДоступныхНастроек);
КомпоновщикНастроек.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию);
Показана особенность при работе с макетом в конструкторе СКД, которая может легко загубить результаты вашей работы
На скринах показано как можно легко испортить Макет из-за своеобразной логики работы конструктора СКД
2020-06-15_15-35-36 (2).jpg
2020-06-...
&НаКлиенте
Процедура ЗагрузитьCSV(Команда) // выполняется при нажатии на кнопку
ДиалогФыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие); //!!!!!!!!!!!!
ДиалогФыбораФайла.Фильтр="csv файл с разделтелями (*.csv)|*.csv|";
ДиалогФыбораФайла.Заголовок = "Выберите файл";
ДиалогФыбораФайла.ИндексФильтра = 0;
описаниеОповещения = Новый ОписаниеОповещения("ГрузимИзФайла", ЭтотОбъект);
ДиалогФыбораФайла.Показать(описаниеОповещения);
КонецПроцедуры
&НаКлиенте
Процедура ГрузимИзФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт // вызываем диалог выбора файла
Если ВыбранныеФайлы <> Неопределено И ВыбранныеФайлы.Количество() > 0 Тогда
// Сообщить("Файл выбран!");
//работаем с файлом
Имяфайла=ВыбранныеФайлы[0];
// Пишем в реестр
сообщить(имяФайла); // вызываем дальнейшую процедуру обработки
Путь=имяФайла; // для сохранения xml понадобится
// читаем файл
ЗагружаемыйФайл = Новый ТекстовыйДокумент;
ЗагружаемыйФайл.Прочитать(ИмяФайла);
Если лист="лист1" тогда
обработатьCSV1(ЗагружаемыйФайл);
конецЕсли;
Иначе
Сообщить("Файл не выбран!");
КонецЕсли;
КонецПроцедуры
// процедуру обработатьCSV1(файл) - можно сделать на клиенте
&наСервере
процедура обработатьCSV1(файл)
для номерстроки=2 по файл.КоличествоСтрок() цикл // первую строку пропускаем т.к. там название полей
строка=файл.получитьСтроку(номерСтроки);
массив=РазложитьСтрокуВМассивПодстрок(строка,";"); // строка csv - файла, преобразованная в массив, дальше с этими данными можно делать что угодно
конецЦикла;
конецПроцедуры
// процедуру РазложитьСтрокуВМассивПодстрок - можно сделать на клиенте, если процедура "обработатьCSV1" тоже имеет директиву &наКлиенте
&наСервере
Функция РазложитьСтрокуВМассивПодстрок(Знач Стр, Разделитель = ",") Экспорт
МассивСтрок = Новый Массив();
Если Разделитель = " " Тогда
Стр = СокрЛП(Стр);
Пока 1=1 Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр,Поз-1));
Стр = СокрЛ(Сред(Стр,Поз));
КонецЦикла;
Иначе
ДлинаРазделителя = СтрДлина(Разделитель);
Пока 1=1 Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр,Поз-1));
Стр = Сред(Стр,Поз+ДлинаРазделителя);
КонецЦикла;
КонецЕсли;
КонецФункции // глРазложить
&НаКлиенте
Процедура ЗагрузитьCSV(Команда) // выполняется при нажатии на кнопку
ДиалогФыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие); //!!!!!!!!!!!!
ДиалогФыбораФайла.Фильтр="csv файл с разделтелями (*.csv)|*.csv|";
ДиалогФыбораФайла.Заголовок = "Выберите файл";
ДиалогФыбораФайла.ИндексФильтра = 0;
описаниеОповещения = Новый ОписаниеОповещения("ГрузимИзФайла", ЭтотОбъект);
ДиалогФыбораФайла.Показать(описаниеОповещения);
КонецПроцедуры
&НаКлиенте
Процедура ГрузимИзФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт // вызываем диалог выбора файла
Если ВыбранныеФайлы <> Неопределено И ВыбранныеФайлы.Количество() > 0 Тогда
// Сообщить("Файл выбран!");
//работаем с файлом
Имяфайла=ВыбранныеФайлы[0];
// Пишем в реестр
сообщить(имяФайла); // вызываем дальнейшую процедуру обработки
Путь=имяФайла; // для сохранения xml понадобится
// читаем файл
ЗагружаемыйФайл = Новый ТекстовыйДокумент;
ЗагружаемыйФайл.Прочитать(ИмяФайла);
Если лист="лист1" тогда
обработатьCSV1(ЗагружаемыйФайл);
конецЕсли;
Иначе
Сообщить("Файл не выбран!");
КонецЕсли;
КонецПроцедуры
// процедуру обработатьCSV1(файл) - можно сделать на клиенте
&наСервере
процедура обработатьCSV1(файл)
для номерстроки=2 по файл.КоличествоСтрок() цикл // первую строку пропускаем т.к. там название полей
строка=файл.получитьСтроку(номерСтроки);
массив=РазложитьСтрокуВМассивПодстрок(строка,";"); // строка csv - файла, преобразованная в массив, дальше с этими данными можно делать что угодно
конецЦикла;
конецПроцедуры
// процедуру РазложитьСтрокуВМассивПодстрок - можно сделать на клиенте, если процедура "обработатьCSV1" тоже имеет директиву &наКлиенте
&наСервере
Функция РазложитьСтрокуВМассивПодстрок(Знач Стр, Разделитель = ",") Экспорт
МассивСтрок = Новый Массив();
Если Разделитель = " " Тогда
Стр = СокрЛП(Стр);
Пока 1=1 Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр,Поз-1));
Стр = СокрЛ(Сред(Стр,Поз));
КонецЦикла;
Иначе
ДлинаРазделителя = СтрДлина(Разделитель);
Пока 1=1 Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр,Поз-1));
Стр = Сред(Стр,Поз+ДлинаРазделителя);
КонецЦикла;
КонецЕсли;
КонецФункции // глРазложить
Для использования синонима отчета/обработки при исполнении на клиенте для подобной универсальной подстановки в разные места - можно завести реквизит формы СинонимОтчета (тип Строка), заполнять его в ПриСозданииНаСервере() этой формы и потом обращаться к нему Форма.СинонимОтчета.
//***********************************************************************
&НаКлиенте
Процедура СохранитьВExcel(Команда)
ИмяФайла = Форма.СинонимОтчета + " (" +
Строка(Формат(ТекущаяДата(),"ДФ=""дд-ММ-гггг""")) + ")"
+".xlsx";
//.....
КонецПроцедуры
&НаКлиентеНаСервереБезКонтекста
Процедура ОбновитьТекстЗаголовка(Форма)
Отчет = Форма.Отчет;
ЗаголовокОтчета = НСтр("ru = '" + Форма.СинонимОтчета + "'") + БухгалтерскиеОтчетыКлиентСервер.ПолучитьПредставлениеПериода(Отчет.НачалоПериода, Отчет.КонецПериода);
Если ЗначениеЗаполнено(Отчет.Организация) И Форма.ИспользуетсяНесколькоОрганизаций Тогда
ЗаголовокОтчета = ЗаголовокОтчета + " " + БухгалтерскиеОтчетыВызовСервераПовтИсп.ПолучитьТекстОрганизация(Отчет.Организация, Отчет.ВключатьОбособленныеПодразделения);
КонецЕсли;
Форма.Заголовок = ЗаголовокОтчета;
КонецПроцедуры
//***********************************************************************
&НаСервере
Функция ВернутьСинонимОтчета()
ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
Возврат ОтчетОбъект.Метаданные().Синоним + " " + ОтчетОбъект.Метаданные().Комментарий;
//Возврат ОтчетОбъект.Метаданные().Синоним;
КонецФункции
//***********************************************************************
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ЭтаФорма.СинонимОтчета = ВернутьСинонимОтчета();
КонецПроцедуры
//***********************************************************************
&НаКлиенте
Процедура СохранитьВExcel(Команда)
ИмяФайла = Форма.СинонимОтчета + " (" +
Строка(Формат(ТекущаяДата(),"ДФ=""дд-ММ-гггг""")) + ")"
+".xlsx";
//.....
КонецПроцедуры
&НаКлиентеНаСервереБезКонтекста
Процедура ОбновитьТекстЗаголовка(Форма)
Отчет = Форма.Отчет;
ЗаголовокОтчета = НСтр("ru = '" + Форма.СинонимОтчета + "'") + БухгалтерскиеОтчетыКлиентСервер.ПолучитьПредставлениеПериода(Отчет.НачалоПериода, Отчет.КонецПериода);
Если ЗначениеЗаполнено(Отчет.Организация) И Форма.ИспользуетсяНесколькоОрганизаций Тогда
ЗаголовокОтчета = ЗаголовокОтчета + " " + БухгалтерскиеОтчетыВызовСервераПовтИсп.ПолучитьТекстОрганизация(Отчет.Организация, Отчет.ВключатьОбособленныеПодразделения);
КонецЕсли;
Форма.Заголовок = ЗаголовокОтчета;
КонецПроцедуры
//***********************************************************************
&НаСервере
Функция ВернутьСинонимОтчета()
ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
Возврат ОтчетОбъект.Метаданные().Синоним + " " + ОтчетОбъект.Метаданные().Комментарий;
//Возврат ОтчетОбъект.Метаданные().Синоним;
КонецФункции
//***********************************************************************
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ЭтаФорма.СинонимОтчета = ВернутьСинонимОтчета();
КонецПроцедуры
/////////////////////////////////////////////////////////////////////////
// РЕГИСТРАЦИЯ ВНЕШНЕЙ ОБРАБОТКИ
Функция СведенияОВнешнейОбработке() Экспорт
ИмяОтчета = ЭтотОбъект.Метаданные().Имя;
Синоним = ЭтотОбъект.Метаданные().Синоним + " " + ЭтотОбъект.Метаданные().Комментарий;
Синоним = ?(ЗначениеЗаполнено(Синоним),Синоним, ИмяОтчета);
РегистрационныеДанные = Новый Структура();
РегистрационныеДанные.Вставить("Вид", "ДополнительнаяОбработка");
РегистрационныеДанные.Вставить("Наименование", Синоним);
РегистрационныеДанные.Вставить("Версия", "1.0");
РегистрационныеДанные.Вставить("БезопасныйРежим", Ложь);
РегистрационныеДанные.Вставить("Информация", "Обработка "+Синоним);
ТаблицаКоманд = ПолучитьТаблицуКоманд();
// Добавим команду в таблицу
ДобавитьКоманду(ТаблицаКоманд, Синоним, "1" , "ОткрытиеФормы", Истина, );
// Сохраним таблицу команд в параметры регистрации обработки
РегистрационныеДанные.Вставить("Команды", ТаблицаКоманд);
Возврат РегистрационныеДанные;
КонецФункции
Функция ПолучитьТаблицуКоманд()
// Создадим пустую таблицу команд и колонки в ней
Команды = Новый ТаблицаЗначений;
// Как будет выглядеть описание печатной формы для пользователя
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
// Имя нашего макета, что бы могли отличить вызванную команду в обработке печати
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
// Тут задается, как должна вызваться команда обработки
// Возможные варианты:
// - ОткрытиеФормы - в этом случае в колонке идентификатор должно быть указано имя формы, которое должна будет открыть система
// - ВызовКлиентскогоМетода - вызвать клиентскую экспортную процедуру из модуля формы обработки
// - ВызовСерверногоМетода - вызвать серверную экспортную процедуру из модуля объекта обработки
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
// Следующий параметр указывает, необходимо ли показывать оповещение при начале и завершению работы обработки. Не имеет смысла при открытии формы
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
// Для печатной формы должен содержать строку ПечатьMXL
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование = "ОткрытиеФормы", ПоказыватьОповещение = Ложь, Модификатор)
// Добавляем команду в таблицу команд по переданному описанию.
// Параметры и их значения можно посмотреть в функции ПолучитьТаблицуКоманд
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
/////////////////////////////////////////////////////////////////////////
// РЕГИСТРАЦИЯ ВНЕШНЕЙ ОБРАБОТКИ
Функция СведенияОВнешнейОбработке() Экспорт
ИмяОтчета = ЭтотОбъект.Метаданные().Имя;
Синоним = ЭтотОбъект.Метаданные().Синоним + " " + ЭтотОбъект.Метаданные().Комментарий;
Синоним = ?(ЗначениеЗаполнено(Синоним),Синоним, ИмяОтчета);
РегистрационныеДанные = Новый Структура();
РегистрационныеДанные.Вставить("Вид", "ДополнительнаяОбработка");
РегистрационныеДанные.Вставить("Наименование", Синоним);
РегистрационныеДанные.Вставить("Версия", "1.0");
РегистрационныеДанные.Вставить("БезопасныйРежим", Ложь);
РегистрационныеДанные.Вставить("Информация", "Обработка "+Синоним);
ТаблицаКоманд = ПолучитьТаблицуКоманд();
// Добавим команду в таблицу
ДобавитьКоманду(ТаблицаКоманд, Синоним, "1" , "ОткрытиеФормы", Истина, );
// Сохраним таблицу команд в параметры регистрации обработки
РегистрационныеДанные.Вставить("Команды", ТаблицаКоманд);
Возврат РегистрационныеДанные;
КонецФункции
Функция ПолучитьТаблицуКоманд()
// Создадим пустую таблицу команд и колонки в ней
Команды = Новый ТаблицаЗначений;
// Как будет выглядеть описание печатной формы для пользователя
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
// Имя нашего макета, что бы могли отличить вызванную команду в обработке печати
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
// Тут задается, как должна вызваться команда обработки
// Возможные варианты:
// - ОткрытиеФормы - в этом случае в колонке идентификатор должно быть указано имя формы, которое должна будет открыть система
// - ВызовКлиентскогоМетода - вызвать клиентскую экспортную процедуру из модуля формы обработки
// - ВызовСерверногоМетода - вызвать серверную экспортную процедуру из модуля объекта обработки
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
// Следующий параметр указывает, необходимо ли показывать оповещение при начале и завершению работы обработки. Не имеет смысла при открытии формы
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
// Для печатной формы должен содержать строку ПечатьMXL
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование = "ОткрытиеФормы", ПоказыватьОповещение = Ложь, Модификатор)
// Добавляем команду в таблицу команд по переданному описанию.
// Параметры и их значения можно посмотреть в функции ПолучитьТаблицуКоманд
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
Функция СведенияОВнешнейОбработке() Экспорт
ИмяОтчета = ЭтотОбъект.Метаданные().Имя;
Синоним = ЭтотОбъект.Метаданные().Синоним;
Синоним = ?(ЗначениеЗаполнено(Синоним),Синоним, ИмяОтчета);
РегистрационныеДанные = Новый Структура;
РегистрационныеДанные.Вставить("Вид","ДополнительныйОтчет"); //может быть – ПечатнаяФорма, ЗаполнениеОбъекта (для вн.обработки), ДополнительныйОтчет, СозданиеСвязанныхОбъектов…
РегистрационныеДанные.Вставить("Наименование", Синоним); //имя под которым обработка будет зарегестрирована в справочнике внешних обработок
РегистрационныеДанные.Вставить("Версия", "1.0");
РегистрационныеДанные.Вставить("БезопасныйРежим", Ложь);
РегистрационныеДанные.Вставить("Информация", "Отчет "+Синоним); //так будет выглядеть описание вн.отчета для пользователя
ТаблицаКоманд = ПолучитьТаблицуКоманд();
// Добавим команду в таблицу
ДобавитьКоманду(ТаблицаКоманд, Синоним, "СформироватьОтчет" , "ОткрытиеФормы", Истина, );
// Сохраним таблицу команд в параметры регистрации обработки
РегистрационныеДанные.Вставить("Команды", ТаблицаКоманд);
Возврат РегистрационныеДанные;
КонецФункции
Функция ПолучитьТаблицуКоманд()
// Создадим пустую таблицу команд и колонки в ней
Команды = Новый ТаблицаЗначений;
// Как будет выглядеть описание печатной формы для пользователя
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
// Имя нашего макета, что бы могли отличить вызванную команду в обработке печати
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
// Тут задается, как должна вызваться команда обработки
// Возможные варианты:
// - ОткрытиеФормы - в этом случае в колонке идентификатор должно быть указано имя формы, которое должна будет открыть система
// - ВызовКлиентскогоМетода - вызвать клиентскую экспортную процедуру из модуля формы обработки
// - ВызовСерверногоМетода - вызвать серверную экспортную процедуру из модуля объекта обработки
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
// Следующий параметр указывает, необходимо ли показывать оповещение при начале и завершению работы обработки. Не имеет смысла при открытии формы
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
// Для печатной формы должен содержать строку ПечатьMXL
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование = "ОткрытиеФормы", ПоказыватьОповещение = Ложь, Модификатор = "ПечатьMXL")
// Добавляем команду в таблицу команд по переданному описанию.
// Параметры и их значения можно посмотреть в функции ПолучитьТаблицуКоманд
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
Функция СведенияОВнешнейОбработке() Экспорт
ИмяОтчета = ЭтотОбъект.Метаданные().Имя;
Синоним = ЭтотОбъект.Метаданные().Синоним;
Синоним = ?(ЗначениеЗаполнено(Синоним),Синоним, ИмяОтчета);
РегистрационныеДанные = Новый Структура;
РегистрационныеДанные.Вставить("Вид","ДополнительныйОтчет"); //может быть – ПечатнаяФорма, ЗаполнениеОбъекта (для вн.обработки), ДополнительныйОтчет, СозданиеСвязанныхОбъектов…
РегистрационныеДанные.Вставить("Наименование", Синоним); //имя под которым обработка будет зарегестрирована в справочнике внешних обработок
РегистрационныеДанные.Вставить("Версия", "1.0");
РегистрационныеДанные.Вставить("БезопасныйРежим", Ложь);
РегистрационныеДанные.Вставить("Информация", "Отчет "+Синоним); //так будет выглядеть описание вн.отчета для пользователя
ТаблицаКоманд = ПолучитьТаблицуКоманд();
// Добавим команду в таблицу
ДобавитьКоманду(ТаблицаКоманд, Синоним, "СформироватьОтчет" , "ОткрытиеФормы", Истина, );
// Сохраним таблицу команд в параметры регистрации обработки
РегистрационныеДанные.Вставить("Команды", ТаблицаКоманд);
Возврат РегистрационныеДанные;
КонецФункции
Функция ПолучитьТаблицуКоманд()
// Создадим пустую таблицу команд и колонки в ней
Команды = Новый ТаблицаЗначений;
// Как будет выглядеть описание печатной формы для пользователя
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
// Имя нашего макета, что бы могли отличить вызванную команду в обработке печати
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
// Тут задается, как должна вызваться команда обработки
// Возможные варианты:
// - ОткрытиеФормы - в этом случае в колонке идентификатор должно быть указано имя формы, которое должна будет открыть система
// - ВызовКлиентскогоМетода - вызвать клиентскую экспортную процедуру из модуля формы обработки
// - ВызовСерверногоМетода - вызвать серверную экспортную процедуру из модуля объекта обработки
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
// Следующий параметр указывает, необходимо ли показывать оповещение при начале и завершению работы обработки. Не имеет смысла при открытии формы
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
// Для печатной формы должен содержать строку ПечатьMXL
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование = "ОткрытиеФормы", ПоказыватьОповещение = Ложь, Модификатор = "ПечатьMXL")
// Добавляем команду в таблицу команд по переданному описанию.
// Параметры и их значения можно посмотреть в функции ПолучитьТаблицуКоманд
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
Сведения о внешней печатной формы для использования совместно с БСП
#Область ОсновныеНастройкиДляПодключенияПечать
Функция ВернутьСтруктуруПараметров()
Структура = Новый Структура();
Структура.Вставить("Документ","Документ.АктОРасхожденияхПриПоступленииТоваров");
Структура.Вставить("Представление",ЭтотОбъект.Метаданные().Представление());
Структура.Вставить("Наименование",ЭтотОбъект.Метаданные().Синоним);
Структура.Вставить("Идентификатор",ЭтотОбъект.Метаданные().Имя);
Структура.Вставить("Версия","1.0.0.0");
Возврат Структура;
КонецФункции
Функция СведенияОВнешнейОбработке() ЭКСПОРТ
Структура = ВернутьСтруктуруПараметров();
Версия = СтандартныеПодсистемыСервер.ВерсияБиблиотеки();
Сведения = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке(Версия);
Сведения.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
Сведения.Версия = Структура.Версия;
МассивНазначений = Новый Массив();
МассивНазначений.Добавить(Структура.Документ);
Сведения.Назначение = МассивНазначений;
Сведения.Наименование = Структура.Наименование;
стр = Сведения.Команды.Добавить();
стр.Представление = Структура.Представление;
стр.Идентификатор = Структура.Идентификатор;
стр.Модификатор = "ПечатьMXL";
стр.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
Возврат Сведения;
КонецФункции
Функция Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) ЭКСПОРТ
Структура = ВернутьСтруктуруПараметров();
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, Структура.Идентификатор) Тогда
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, Структура.Идентификатор, Структура.Представление, СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати));
КонецЕсли;
КонецФункции
Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати)
ТабличныйДокумент = Новый ТабличныйДокумент;
Возврат ТабличныйДокумент;
КонецФункции
#КонецОбласти
#Область ОсновныеНастройкиДляПодключенияПечать
Функция ВернутьСтруктуруПараметров()
Структура = Новый Структура();
Структура.Вставить("Документ","Документ.АктОРасхожденияхПриПоступленииТоваров");
Структура.Вставить("Представление",ЭтотОбъект.Метаданные().Представление());
Структура.Вставить("Наименование",ЭтотОбъект.Метаданные().Синоним);
Структура.Вставить("Идентификатор",ЭтотОбъект.Метаданные().Имя);
Структура.Вставить("Версия","1.0.0.0");
Возврат Структура;
КонецФункции
Функция СведенияОВнешнейОбработке() ЭКСПОРТ
Структура = ВернутьСтруктуруПараметров();
Версия = СтандартныеПодсистемыСервер.ВерсияБиблиотеки();
Сведения = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке(Версия);
Сведения.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
Сведения.Версия = Структура.Версия;
МассивНазначений = Новый Массив();
МассивНазначений.Добавить(Структура.Документ);
Сведения.Назначение = МассивНазначений;
Сведения.Наименование = Структура.Наименование;
стр = Сведения.Команды.Добавить();
стр.Представление = Структура.Представление;
стр.Идентификатор = Структура.Идентификатор;
стр.Модификатор = "ПечатьMXL";
стр.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
Возврат Сведения;
КонецФункции
Функция Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) ЭКСПОРТ
Структура = ВернутьСтруктуруПараметров();
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, Структура.Идентификатор) Тогда
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, Структура.Идентификатор, Структура.Представление, СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати));
КонецЕсли;
КонецФункции
Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати)
ТабличныйДокумент = Новый ТабличныйДокумент;
Возврат ТабличныйДокумент;
КонецФункции
#КонецОбласти
Нужно использовать функцию после формирования табличного документа
Функция ОбработатьЗаголовки(ТабДок)
ВысотаФ = ТабДок.ФиксацияСверху;
ШиринаФ = ТабДок.ФиксацияСлева;
ШиринаТаблицы = ТабДок.ШиринаТаблицы;
МассивМассивовОбъединяемыхОбластей = Новый Массив;
МассивОбъединяемыхОбластей = Новый Массив;
НачальнаяКолонка = ШиринаФ + 1;
КонечнаяКолонка = ШиринаТаблицы;
МассивОбъединяемыхОбластей.Добавить(Новый Структура("НачальнаяКолонка, КонечнаяКолонка", НачальнаяКолонка, КонечнаяКолонка));
МассивМассивовОбъединяемыхОбластей.Добавить(МассивОбъединяемыхОбластей);
Строка = 1;
Пока Строка <= ВысотаФ Цикл
Если Строка = МассивМассивовОбъединяемыхОбластей.Количество() Тогда
Для Каждого ОбъединяемаяОбласть Из МассивМассивовОбъединяемыхОбластей[Строка-1] Цикл
НачальнаяКолонка = ОбъединяемаяОбласть.НачальнаяКолонка;
КонечнаяКолонка = ОбъединяемаяОбласть.КонечнаяКолонка;
Колонка = НачальнаяКолонка;
Пока Колонка <= КонечнаяКолонка Цикл
Если НЕ ОбъединятьЯчейки(ТабДок, Строка, Колонка) ИЛИ Колонка = КонечнаяКолонка Тогда
Если Колонка <> НачальнаяКолонка Тогда
МассивОбъединяемыхОбластей.Добавить(Новый Структура("НачальнаяКолонка, КонечнаяКолонка", НачальнаяКолонка, Колонка));
КонецЕсли;
НачальнаяКолонка = Колонка + 1;
КонецЕсли;
Колонка = Колонка + 1;
КонецЦикла;
КонецЦикла;
Если МассивОбъединяемыхОбластей.Количество() = 0 И ОбъединяемаяОбласть.НачальнаяКолонка = ШиринаФ + 1 И ОбъединяемаяОбласть.КонечнаяКолонка = ШиринаТаблицы Тогда
МассивОбъединяемыхОбластей.Добавить(Новый Структура("НачальнаяКолонка, КонечнаяКолонка", ОбъединяемаяОбласть.НачальнаяКолонка, ОбъединяемаяОбласть.КонечнаяКолонка));
КонецЕсли;
МассивМассивовОбъединяемыхОбластей.Добавить(МассивОбъединяемыхОбластей);
МассивОбъединяемыхОбластей = Новый Массив;
КонецЕсли;
Строка = Строка + 1;
КонецЦикла;
Строка = 1;
Пока Строка < МассивМассивовОбъединяемыхОбластей.Количество() Цикл
Для Каждого ОбъединяемаяОбласть Из МассивМассивовОбъединяемыхОбластей[Строка] Цикл
ТекстЗаголовка = ТабДок.Область(Строка, ОбъединяемаяОбласть.НачальнаяКолонка).Текст;
ОбъединяемаяОбласть = ТабДок.Область(Строка, ОбъединяемаяОбласть.НачальнаяКолонка, Строка, ОбъединяемаяОбласть.КонечнаяКолонка);
ОбъединяемаяОбласть.Объединить();
ОбъединяемаяОбласть.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
ОбъединяемаяОбласть.Текст = ТекстЗаголовка;
КонецЦикла;
Строка = Строка + 1;
КонецЦикла;
Возврат ТабДок;
КонецФункции
Функция ОбъединятьЯчейки(ТабДок, Строка, НачальнаяКолонка)
Ячейка = ТабДок.Область(Строка, НачальнаяКолонка);
ЯчейкаСлед = ТабДок.Область(Строка, НачальнаяКолонка+1);
Если ПустаяСтрока(Ячейка.Текст) Тогда
Возврат ложь
ИначеЕсли
Ячейка.Текст = ЯчейкаСлед.Текст
И Ячейка.Верх = Ячейка.Низ И ЯчейкаСлед.Верх = ЯчейкаСлед.Низ Тогда
Возврат Истина;
Иначе
Возврат ложь;
КонецЕсли;
КонецФункции
Функция ОбработатьЗаголовки(ТабДок)
ВысотаФ = ТабДок.ФиксацияСверху;
ШиринаФ = ТабДок.ФиксацияСлева;
ШиринаТаблицы = ТабДок.ШиринаТаблицы;
МассивМассивовОбъединяемыхОбластей = Новый Массив;
МассивОбъединяемыхОбластей = Новый Массив;
НачальнаяКолонка = ШиринаФ + 1;
КонечнаяКолонка = ШиринаТаблицы;
МассивОбъединяемыхОбластей.Добавить(Новый Структура("НачальнаяКолонка, КонечнаяКолонка", НачальнаяКолонка, КонечнаяКолонка));
МассивМассивовОбъединяемыхОбластей.Добавить(МассивОбъединяемыхОбластей);
Строка = 1;
Пока Строка <= ВысотаФ Цикл
Если Строка = МассивМассивовОбъединяемыхОбластей.Количество() Тогда
Для Каждого ОбъединяемаяОбласть Из МассивМассивовОбъединяемыхОбластей[Строка-1] Цикл
НачальнаяКолонка = ОбъединяемаяОбласть.НачальнаяКолонка;
КонечнаяКолонка = ОбъединяемаяОбласть.КонечнаяКолонка;
Колонка = НачальнаяКолонка;
Пока Колонка <= КонечнаяКолонка Цикл
Если НЕ ОбъединятьЯчейки(ТабДок, Строка, Колонка) ИЛИ Колонка = КонечнаяКолонка Тогда
Если Колонка <> НачальнаяКолонка Тогда
МассивОбъединяемыхОбластей.Добавить(Новый Структура("НачальнаяКолонка, КонечнаяКолонка", НачальнаяКолонка, Колонка));
КонецЕсли;
НачальнаяКолонка = Колонка + 1;
КонецЕсли;
Колонка = Колонка + 1;
КонецЦикла;
КонецЦикла;
Если МассивОбъединяемыхОбластей.Количество() = 0 И ОбъединяемаяОбласть.НачальнаяКолонка = ШиринаФ + 1 И ОбъединяемаяОбласть.КонечнаяКолонка = ШиринаТаблицы Тогда
МассивОбъединяемыхОбластей.Добавить(Новый Структура("НачальнаяКолонка, КонечнаяКолонка", ОбъединяемаяОбласть.НачальнаяКолонка, ОбъединяемаяОбласть.КонечнаяКолонка));
КонецЕсли;
МассивМассивовОбъединяемыхОбластей.Добавить(МассивОбъединяемыхОбластей);
МассивОбъединяемыхОбластей = Новый Массив;
КонецЕсли;
Строка = Строка + 1;
КонецЦикла;
Строка = 1;
Пока Строка < МассивМассивовОбъединяемыхОбластей.Количество() Цикл
Для Каждого ОбъединяемаяОбласть Из МассивМассивовОбъединяемыхОбластей[Строка] Цикл
ТекстЗаголовка = ТабДок.Область(Строка, ОбъединяемаяОбласть.НачальнаяКолонка).Текст;
ОбъединяемаяОбласть = ТабДок.Область(Строка, ОбъединяемаяОбласть.НачальнаяКолонка, Строка, ОбъединяемаяОбласть.КонечнаяКолонка);
ОбъединяемаяОбласть.Объединить();
ОбъединяемаяОбласть.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
ОбъединяемаяОбласть.Текст = ТекстЗаголовка;
КонецЦикла;
Строка = Строка + 1;
КонецЦикла;
Возврат ТабДок;
КонецФункции
Функция ОбъединятьЯчейки(ТабДок, Строка, НачальнаяКолонка)
Ячейка = ТабДок.Область(Строка, НачальнаяКолонка);
ЯчейкаСлед = ТабДок.Область(Строка, НачальнаяКолонка+1);
Если ПустаяСтрока(Ячейка.Текст) Тогда
Возврат ложь
ИначеЕсли
Ячейка.Текст = ЯчейкаСлед.Текст
И Ячейка.Верх = Ячейка.Низ И ЯчейкаСлед.Верх = ЯчейкаСлед.Низ Тогда
Возврат Истина;
Иначе
Возврат ложь;
КонецЕсли;
КонецФункции
МодульУправлениеПечатьюКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("УправлениеПечатьюКлиент");
ИдентификаторПечатнойФормы = "ПечатьДокумент";
КоллекцияПечатныхФорм = МодульУправлениеПечатьюКлиент.НоваяКоллекцияПечатныхФорм(ИдентификаторПечатнойФормы);
ПечатнаяФорма = МодульУправлениеПечатьюКлиент.ОписаниеПечатнойФормы(КоллекцияПечатныхФорм, ИдентификаторПечатнойФормы);
ПечатнаяФорма.СинонимМакета = НСтр("ru = 'Наименование заголовка'");
ПечатнаяФорма.ТабличныйДокумент = ТабличныйДокумент; //указываем подготовленный табличный документ
ПечатнаяФорма.ТабличныйДокумент.АвтоМасштаб = Истина; //по ширине страницы
МодульУправлениеПечатьюКлиент.ПечатьДокументов(КоллекцияПечатныхФорм);
МодульУправлениеПечатьюКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("УправлениеПечатьюКлиент");
ИдентификаторПечатнойФормы = "ПечатьДокумент";
КоллекцияПечатныхФорм = МодульУправлениеПечатьюКлиент.НоваяКоллекцияПечатныхФорм(ИдентификаторПечатнойФормы);
ПечатнаяФорма = МодульУправлениеПечатьюКлиент.ОписаниеПечатнойФормы(КоллекцияПечатныхФорм, ИдентификаторПечатнойФормы);
ПечатнаяФорма.СинонимМакета = НСтр("ru = 'Наименование заголовка'");
ПечатнаяФорма.ТабличныйДокумент = ТабличныйДокумент; //указываем подготовленный табличный документ
ПечатнаяФорма.ТабличныйДокумент.АвтоМасштаб = Истина; //по ширине страницы
МодульУправлениеПечатьюКлиент.ПечатьДокументов(КоллекцияПечатныхФорм);
Процедура ЮКОЗ_ЗагрузкаКП() Экспорт
//Инициализируем константные переменные
КаталогВрФл = КаталогВременныхФайлов();
ВидНоменклатуры = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ВидыНоменклатурыТовар");
ЕдиницаИзмШТ = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ЕдиницаИзмерения_ШТ");
ПриоритетСредний = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ПриоритетСредний");
СкладОсновной = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("СкладОсновной");
ТиповоеСоглашение = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ТиповоеСоглашение");
ВалютаДок = Константы.ВалютаРегламентированногоУчета.Получить();
АдресFTP = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("АдресFTP");
ЛогинFTP = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ЛогинFTP");
ПарольFTP = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ПарольFTP");
//Соединямся с FTP-сервером и ищем необработанные файлы xml
ФТПСоединение = Новый FTPСоединение(АдресFTP,, ЛогинFTP, ПарольFTP,, Истина);
НайдемФайлаНаФТП = ФТПСоединение.НайтиФайлы("/", "*.xml");
//Если файлов нет, значит завершаем работу
Если НайдемФайлаНаФТП.Количество() = 0 Тогда
ФТПСоединение = Неопределено;
Возврат;
КонецЕсли;
//Подготавливаем таблицу значений для заполнения загружаемыми данными
ДанныеИзФайлаТовары = Новый ТаблицаЗначений();
ДанныеИзФайлаТовары.Колонки.Добавить("Артикул");
ДанныеИзФайлаТовары.Колонки.Добавить("ИД");
ДанныеИзФайлаТовары.Колонки.Добавить("Производитель");
ДанныеИзФайлаТовары.Колонки.Добавить("Номенклатура");
ДанныеИзФайлаТовары.Колонки.Добавить("Количество");
ДанныеИзФайлаТовары.Колонки.Добавить("Цена");
ДанныеИзФайлаТовары.Колонки.Добавить("Размер");
ДанныеИзФайлаТовары.Колонки.Добавить("Цвет");
ДанныеИзФайлаТовары.Колонки.Добавить("Серия");
ДанныеИзФайлаТовары.Колонки.Добавить("ЦенаСоСкидкой");
//Циклом обходим каждый найденный на FTP файл xml
Для каждого ФайлФТП из НайдемФайлаНаФТП Цикл
//Очищаем нашу таблицу значений, чтобы она могла хранить данные только по одному файлу xml
ДанныеИзФайлаТовары.Очистить();
//Получаем номер коммерческого предложения из имени файла xml
НомерКП = ФайлФТП.ИмяБезРасширения;
//Очищаем дату коммерческого предложения кототрую мы впоследствии возьмом из тела файла xml
ДатаКП = "";
//Обернём код в попытку, мало ли будут ошибки при загрузке и обработке файла
Попытка
//Загружаем файл на локальный компьютер
ПутьКФайлуОбъект = КаталогВрФл + ФайлФТП.Имя;
ФТПСоединение.Получить(ФайлФТП.ПолноеИмя, ПутьКФайлуОбъект);
//Перемещаем загруженный файл в директорию обработанных файлов на FTP
//Специально помещаем в начале, чтобы регламентное задание в случае ошибок в этом файле каждый раз не спотыкалось об него
ФТПСоединение.Переместить(ФайлФТП.ПолноеИмя, "OldFiles" + "\" + ФайлФТП.Имя);
//Инициализируем чтение файла xml
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлуОбъект);
//Циклом обходим узлы XML файла и при совпадении с нужным именем узла записываем его значение в нашу таблицу значений
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда Продолжить; КонецЕсли;
ИмяУзла = ЧтениеXML.ЛокальноеИмя;
Если ИмяУзла = "PRODUCT" Тогда
НоваяСтрока = ДанныеИзФайлаТовары.Добавить();
Продолжить;
КонецЕсли;
Если ИмяУзла = "ID" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.ИД = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "ARTICLE" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Артикул = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "SIZE" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Размер = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "COLOR" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Цвет = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "NAME" И ЧтениеXML.КонтекстПространствИмен.Глубина = 5 Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Серия = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "PROPERTY_PROVIDER_NAME" И ЧтениеXML.КонтекстПространствИмен.Глубина = 5 Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Производитель = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "NAME" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Номенклатура = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "QUANTITY" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Количество = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "PRICE" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Цена = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "PRICE_DISCOUNT" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.ЦенаСоСкидкой = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "DATE" Тогда
ЧтениеXML.Прочитать();
ДатаСтр = СокрЛП(ЧтениеXML.Значение);
ДатаКП = Дата(ДатаСтр);
Продолжить;
КонецЕсли;
КонецЦикла;
//Закрываем чтение XML и удаляем ранее загруженный временный файл из нашего компьютера
ЧтениеXML.Закрыть();
УдалитьФайлы(ПутьКФайлуОбъект);
//Дата коммерческого предложения обязательно должна быть заполнена, если нет, то вызываем ошибку с пояснением для журнала регистрации
Если НЕ ЗначениеЗаполнено(ДатаКП) Тогда
ВызватьИсключение "Пустая дата по КП " + НомерКП;
КонецЕсли;
//Запросом найдем уже созданный ранее заказ клиента по загружаемому файлу
//Плохо, что запрос в цикле, но в данном случае можно ;) дабы не усложнять код.
ЗапросСущЗаказа = Новый Запрос();
ЗапросСущЗаказа.УстановитьПараметр("НомерКП", НомерКП);
ЗапросСущЗаказа.УстановитьПараметр("ДатаКП", НачалоДня(ДатаКП));
ЗапросСущЗаказа.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
| ЗаказКлиента.Ссылка КАК Ссылка,
| ЗаказКлиента.Проведен КАК Проведен
|ИЗ
| Документ.ЗаказКлиента КАК ЗаказКлиента
|ГДЕ
| ЗаказКлиента.НомерПоДаннымКлиента = &НомерКП
| И ЗаказКлиента.ДатаПоДаннымКлиента = &ДатаКП";
Результат_ЗапросСущЗаказа = ЗапросСущЗаказа.Выполнить().Выбрать();
//Если заказ клиента найден и он проведен, то обновлять\изменять мы его уже не можем и вызываем ошибку с пояснением,
//если еще не проведен, то получаем ссылку на документ и работаем дальше
Если Результат_ЗапросСущЗаказа.Следующий() Тогда
Если Результат_ЗапросСущЗаказа.Проведен Тогда
ВызватьИсключение "Заказ уже проведен по КП " + НомерКП;
КонецЕсли;
ДокЗаказ = Результат_ЗапросСущЗаказа.Ссылка.ПолучитьОбъект();
//Если заказ клиента по загружаемому xml файлу еще не было, то создаем и заполняем его
Иначе
ДокЗаказ = Документы.ЗаказКлиента.СоздатьДокумент();
ДокЗаказ.Дата = ТекущаяДата();
ДокЗаказ.ЮКОЗ_НомерКПИзСайта = НомерКП;
ДокЗаказ.Приоритет = ПриоритетСредний;
ДокЗаказ.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.РеализацияКлиенту;
ДокЗаказ.ЦенаВключаетНДС = Истина;
ДокЗаказ.НалогообложениеНДС = Перечисления.ТипыНалогообложенияНДС.ПродажаОблагаетсяНДС;
ДокЗаказ.НомерПоДаннымКлиента = НомерКП;
ДокЗаказ.ДатаПоДаннымКлиента = ДатаКП;
ДокЗаказ.Склад = СкладОсновной;
ДокЗаказ.Статус = Перечисления.СтатусыЗаказовКлиентов.КОтгрузке;
ДокЗаказ.ЮКОЗ_Статус = Перечисления.ЮКОЗ_СтатусыЗаказовКлиентов.Согласование;
ДокЗаказ.Валюта = ВалютаДок;
ДокЗаказ.Соглашение = ТиповоеСоглашение;
ДокЗаказ.НеОтгружатьЧастями = Истина;
ДокЗаказ.ПорядокОплаты = Перечисления.ПорядокОплатыПоСоглашениям.РасчетыВВалютеОплатаВВалюте;
ДокЗаказ.ФормаОплаты = Перечисления.ФормыОплаты.Безналичная;
КонецЕсли;
//Очистим табличную часть Товары (на тот случай, если заказ клиента уже был ранее создан и там были какие-то данные)
ДокЗаказ.Товары.Очистить();
//Обходим данные из файла через нашу таблицу значений
Для каждого стр из ДанныеИзФайлаТовары Цикл
//Проверям на заполнение обязательный полей (артикул, производитель, номенклатура), если хоть что-то не заполнено, то вызываем ошибку с пояснением
Если НЕ ЗначениеЗаполнено(стр.Артикул) И НЕ ЗначениеЗаполнено(стр.ИД) Тогда
ВызватьИсключение "Пустой артикул и ID по КП " + НомерКП;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(стр.Производитель) Тогда
ВызватьИсключение "Пустой производитель по КП " + НомерКП;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(стр.Номенклатура) Тогда
ВызватьИсключение "Пустая номенклатура по КП " + НомерКП;
КонецЕсли;
//Пытаемся найти уже созданную номенклатуру по артикулу, а если он не заполнен, то по ИД.
ЗапросСущТовара = Новый Запрос();
ЗапросСущТовара.УстановитьПараметр("ИД", стр.ИД);
ЗапросСущТовара.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ" + Символы.ПС;
Если ЗначениеЗаполнено(стр.Артикул) Тогда
ЗапросСущТовара.Текст = ЗапросСущТовара.Текст + "Номенклатура.Артикул = &Артикул";
Иначе
ЗапросСущТовара.Текст = ЗапросСущТовара.Текст + "Номенклатура.ЮКОЗ_IDИзСайта = &ИД";
КонецЕсли;
Результат_ЗапросСущТовара = ЗапросСущТовара.Выполнить().Выбрать();
//Формируем представление строки описания номенклатуры (строковая характеристика)
ДобТоварЮКОЗ_Характеристика = ?(ЗначениеЗаполнено(стр.Серия), стр.Серия + ", ", "") +
?(ЗначениеЗаполнено(стр.Размер), стр.Размер + ", ", "") +
?(ЗначениеЗаполнено(стр.Цвет), стр.Цвет, "");
//Получаем ссылку на номенклатуру если она найдена
Если Результат_ЗапросСущТовара.Следующий() Тогда
ТоварСсылка = Результат_ЗапросСущТовара.Ссылка;
//Если номенклатура не найдена, то создаем её
Иначе
ТоварНовый = Справочники.Номенклатура.СоздатьЭлемент();
//Каждая номенлатура должна находится в своей группе в справочнике номенклатура, где название группы - это наименование производителя
//проверяем это запросом
ЗапросСущГруппы = Новый Запрос();
ЗапросСущГруппы.УстановитьПараметр("Производитель", стр.Производитель);
ЗапросСущГруппы.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Наименование = &Производитель
| И Номенклатура.ЭтоГруппа";
Результат_ЗапросСущГруппы = ЗапросСущГруппы.Выполнить().Выбрать();
//Если группа найдено, то берем ссылку на неё
Если Результат_ЗапросСущГруппы.Следующий() Тогда
ГруппаТовараСсылка = Результат_ЗапросСущГруппы.Ссылка;
//Если группа не найдена, то создаем её
Иначе
ГруппаТовараСсылка = Справочники.Номенклатура.СоздатьГруппу();
ГруппаТовараСсылка.Наименование = стр.Производитель;
ГруппаТовараСсылка.Записать();
ГруппаТовараСсылка = ГруппаТовараСсылка.Ссылка;
КонецЕсли;
//Указываем, что номенклатуру мы создаем в группе которую нашли\создали чуть ранее
ТоварНовый.Родитель = ГруппаТовараСсылка;
//Формируем представление наименования номенклатуры, оно должно содержать артикул, а если его нет, то ИД
//Также записываем артикул, если его нет, то ИД вместо него.
Если ЗначениеЗаполнено(стр.Артикул) Тогда
ТоварНовый.Артикул = стр.Артикул;
ТоварНовый.Наименование = Строка(?(ЗначениеЗаполнено(стр.Артикул), "(" + стр.Артикул + ") ", "") + стр.Номенклатура);
Иначе
ТоварНовый.Наименование = Строка(?(ЗначениеЗаполнено(стр.ИД), "(" + стр.ИД + ") ", "") + стр.Номенклатура);
ТоварНовый.Артикул = стр.ИД;
КонецЕсли;
//Добавляем в наименование номенклатуры строковое описание номенклатуры, которое мы сформировали ранее,
//при условии, что описание номенклатуры есть и оно уже не встречается в наименовании номенклатуры
Если ЗначениеЗаполнено(ДобТоварЮКОЗ_Характеристика) Тогда
Если СтрНайти(СтрЗаменить(ТоварНовый.Наименование, ",", ""),
СтрЗаменить(ДобТоварЮКОЗ_Характеристика, ",", "")) = 0 Тогда
ТоварНовый.Наименование = ТоварНовый.Наименование + ", " + ДобТоварЮКОЗ_Характеристика;
КонецЕсли;
КонецЕсли;
//Заполняем остальные поля номенклатуры
ТоварНовый.ЮКОЗ_IDИзСайта = стр.ИД;
ТоварНовый.ТипНоменклатуры = Перечисления.ТипыНоменклатуры.Товар;
ТоварНовый.ВидНоменклатуры = ВидНоменклатуры;
ТоварНовый.НаименованиеПолное = стр.Номенклатура + ?(ЗначениеЗаполнено(ДобТоварЮКОЗ_Характеристика),
", " + ДобТоварЮКОЗ_Характеристика, "");
ТоварНовый.СтавкаНДС = Перечисления.СтавкиНДС.НДС20;
ТоварНовый.ЕдиницаИзмерения = ЕдиницаИзмШТ;
ТоварНовый.ЕдиницаДляОтчетов = ЕдиницаИзмШТ;
ТоварНовый.ИспользованиеХарактеристик = Перечисления.ВариантыИспользованияХарактеристикНоменклатуры.НеИспользовать;
ТоварНовый.ВариантОформленияПродажи = Перечисления.ВариантыОформленияПродажи.РеализацияТоваровУслуг;
//Ищем производителя, если его нет, то создаем нового и указываем его в номенклатуре
ПроизводительСсылка = Справочники.Производители.НайтиПоНаименованию(стр.Производитель);
Если НЕ ЗначениеЗаполнено(ПроизводительСсылка) Тогда
НовыйПроизводитель = Справочники.Производители.СоздатьЭлемент();
НовыйПроизводитель.Наименование = стр.Производитель;
НовыйПроизводитель.Записать();
ПроизводительСсылка = НовыйПроизводитель.Ссылка;
КонецЕсли;
ТоварНовый.Производитель = ПроизводительСсылка;
//Записываем новую номенклатуру и получаем ссылку на неё
ТоварНовый.Записать();
ТоварСсылка = ТоварНовый.Ссылка;
КонецЕсли;
//Добавляем в табличную часть Товары номенклатуру с заполнением данных из файла xml
ДобТовар = ДокЗаказ.Товары.Добавить();
ДобТовар.Номенклатура = ТоварСсылка;
ДобТовар.Количество = стр.Количество;
ДобТовар.КоличествоУпаковок = стр.Количество;
ДобТовар.Упаковка = ДобТовар.Номенклатура.ЕдиницаИзмерения;
ДобТовар.Цена = стр.Цена;
ДобТовар.СтавкаНДС = ДобТовар.Номенклатура.СтавкаНДС;
ДобТовар.Склад = СкладОсновной;
ДобТовар.ЮКОЗ_Характеристика = ДобТоварЮКОЗ_Характеристика;
//Вычисляем процент ручной скидки, если в файле xml была указана цена со скидкой и она меньше, чем обычная цена
Если ЗначениеЗаполнено(стр.ЦенаСоСкидкой) И ЗначениеЗаполнено(стр.Цена) Тогда
стрЦенаСоСкидкой = Число(стр.ЦенаСоСкидкой);
стрЦена = Число(стр.Цена);
Если стрЦенаСоСкидкой > 0 И стрЦена > 0 И стрЦена > стрЦенаСоСкидкой Тогда
ДобТовар.ПроцентРучнойСкидки = (стрЦенаСоСкидкой / стрЦена - 1) * 100 * -1;
КонецЕсли;
КонецЕсли;
КонецЦикла;
//Посчитаем сумму строки, а также НДС
СтруктураПересчетаСуммы = ОбработкаТабличнойЧастиКлиентСервер.ПараметрыПересчетаСуммыНДСВСтрокеТЧ(ДокЗаказ);
СтруктураДействий = Новый Структура;
СтруктураДействий.Вставить("ПересчитатьСумму", "КоличествоУпаковок");
СтруктураДействий.Вставить("ПересчитатьСуммуНДС", СтруктураПересчетаСуммы);
СтруктураДействий.Вставить("ПересчитатьСуммуСНДС", СтруктураПересчетаСуммы);
ОбработкаТабличнойЧастиСервер.ОбработатьТЧ(ДокЗаказ.Товары, СтруктураДействий, Неопределено);
//Запишем заказ клиента без проведения
ДокЗаказ.Записать(РежимЗаписиДокумента.Запись);
//Обработаем исключения в блоке попытки с записью в журнал регистрации для дальнейшего анализа
Исключение
ЗаписьЖурналаРегистрации("Ошибка обработки КП из сайта: " + ОписаниеОшибки(), УровеньЖурналаРегистрации.Ошибка);
КонецПопытки;
КонецЦикла;
//После обработки всех файлов, закроем FTP соединение.
ФТПСоединение = Неопределено;
КонецПроцедуры
Процедура ЮКОЗ_ЗагрузкаКП() Экспорт
//Инициализируем константные переменные
КаталогВрФл = КаталогВременныхФайлов();
ВидНоменклатуры = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ВидыНоменклатурыТовар");
ЕдиницаИзмШТ = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ЕдиницаИзмерения_ШТ");
ПриоритетСредний = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ПриоритетСредний");
СкладОсновной = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("СкладОсновной");
ТиповоеСоглашение = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ТиповоеСоглашение");
ВалютаДок = Константы.ВалютаРегламентированногоУчета.Получить();
АдресFTP = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("АдресFTP");
ЛогинFTP = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ЛогинFTP");
ПарольFTP = РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ПарольFTP");
//Соединямся с FTP-сервером и ищем необработанные файлы xml
ФТПСоединение = Новый FTPСоединение(АдресFTP,, ЛогинFTP, ПарольFTP,, Истина);
НайдемФайлаНаФТП = ФТПСоединение.НайтиФайлы("/", "*.xml");
//Если файлов нет, значит завершаем работу
Если НайдемФайлаНаФТП.Количество() = 0 Тогда
ФТПСоединение = Неопределено;
Возврат;
КонецЕсли;
//Подготавливаем таблицу значений для заполнения загружаемыми данными
ДанныеИзФайлаТовары = Новый ТаблицаЗначений();
ДанныеИзФайлаТовары.Колонки.Добавить("Артикул");
ДанныеИзФайлаТовары.Колонки.Добавить("ИД");
ДанныеИзФайлаТовары.Колонки.Добавить("Производитель");
ДанныеИзФайлаТовары.Колонки.Добавить("Номенклатура");
ДанныеИзФайлаТовары.Колонки.Добавить("Количество");
ДанныеИзФайлаТовары.Колонки.Добавить("Цена");
ДанныеИзФайлаТовары.Колонки.Добавить("Размер");
ДанныеИзФайлаТовары.Колонки.Добавить("Цвет");
ДанныеИзФайлаТовары.Колонки.Добавить("Серия");
ДанныеИзФайлаТовары.Колонки.Добавить("ЦенаСоСкидкой");
//Циклом обходим каждый найденный на FTP файл xml
Для каждого ФайлФТП из НайдемФайлаНаФТП Цикл
//Очищаем нашу таблицу значений, чтобы она могла хранить данные только по одному файлу xml
ДанныеИзФайлаТовары.Очистить();
//Получаем номер коммерческого предложения из имени файла xml
НомерКП = ФайлФТП.ИмяБезРасширения;
//Очищаем дату коммерческого предложения кототрую мы впоследствии возьмом из тела файла xml
ДатаКП = "";
//Обернём код в попытку, мало ли будут ошибки при загрузке и обработке файла
Попытка
//Загружаем файл на локальный компьютер
ПутьКФайлуОбъект = КаталогВрФл + ФайлФТП.Имя;
ФТПСоединение.Получить(ФайлФТП.ПолноеИмя, ПутьКФайлуОбъект);
//Перемещаем загруженный файл в директорию обработанных файлов на FTP
//Специально помещаем в начале, чтобы регламентное задание в случае ошибок в этом файле каждый раз не спотыкалось об него
ФТПСоединение.Переместить(ФайлФТП.ПолноеИмя, "OldFiles" + "\" + ФайлФТП.Имя);
//Инициализируем чтение файла xml
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлуОбъект);
//Циклом обходим узлы XML файла и при совпадении с нужным именем узла записываем его значение в нашу таблицу значений
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда Продолжить; КонецЕсли;
ИмяУзла = ЧтениеXML.ЛокальноеИмя;
Если ИмяУзла = "PRODUCT" Тогда
НоваяСтрока = ДанныеИзФайлаТовары.Добавить();
Продолжить;
КонецЕсли;
Если ИмяУзла = "ID" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.ИД = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "ARTICLE" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Артикул = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "SIZE" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Размер = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "COLOR" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Цвет = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "NAME" И ЧтениеXML.КонтекстПространствИмен.Глубина = 5 Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Серия = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "PROPERTY_PROVIDER_NAME" И ЧтениеXML.КонтекстПространствИмен.Глубина = 5 Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Производитель = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "NAME" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Номенклатура = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "QUANTITY" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Количество = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "PRICE" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.Цена = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "PRICE_DISCOUNT" Тогда
ЧтениеXML.Прочитать();
НоваяСтрока.ЦенаСоСкидкой = СокрЛП(ЧтениеXML.Значение);
Продолжить;
КонецЕсли;
Если ИмяУзла = "DATE" Тогда
ЧтениеXML.Прочитать();
ДатаСтр = СокрЛП(ЧтениеXML.Значение);
ДатаКП = Дата(ДатаСтр);
Продолжить;
КонецЕсли;
КонецЦикла;
//Закрываем чтение XML и удаляем ранее загруженный временный файл из нашего компьютера
ЧтениеXML.Закрыть();
УдалитьФайлы(ПутьКФайлуОбъект);
//Дата коммерческого предложения обязательно должна быть заполнена, если нет, то вызываем ошибку с пояснением для журнала регистрации
Если НЕ ЗначениеЗаполнено(ДатаКП) Тогда
ВызватьИсключение "Пустая дата по КП " + НомерКП;
КонецЕсли;
//Запросом найдем уже созданный ранее заказ клиента по загружаемому файлу
//Плохо, что запрос в цикле, но в данном случае можно ;) дабы не усложнять код.
ЗапросСущЗаказа = Новый Запрос();
ЗапросСущЗаказа.УстановитьПараметр("НомерКП", НомерКП);
ЗапросСущЗаказа.УстановитьПараметр("ДатаКП", НачалоДня(ДатаКП));
ЗапросСущЗаказа.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
| ЗаказКлиента.Ссылка КАК Ссылка,
| ЗаказКлиента.Проведен КАК Проведен
|ИЗ
| Документ.ЗаказКлиента КАК ЗаказКлиента
|ГДЕ
| ЗаказКлиента.НомерПоДаннымКлиента = &НомерКП
| И ЗаказКлиента.ДатаПоДаннымКлиента = &ДатаКП";
Результат_ЗапросСущЗаказа = ЗапросСущЗаказа.Выполнить().Выбрать();
//Если заказ клиента найден и он проведен, то обновлять\изменять мы его уже не можем и вызываем ошибку с пояснением,
//если еще не проведен, то получаем ссылку на документ и работаем дальше
Если Результат_ЗапросСущЗаказа.Следующий() Тогда
Если Результат_ЗапросСущЗаказа.Проведен Тогда
ВызватьИсключение "Заказ уже проведен по КП " + НомерКП;
КонецЕсли;
ДокЗаказ = Результат_ЗапросСущЗаказа.Ссылка.ПолучитьОбъект();
//Если заказ клиента по загружаемому xml файлу еще не было, то создаем и заполняем его
Иначе
ДокЗаказ = Документы.ЗаказКлиента.СоздатьДокумент();
ДокЗаказ.Дата = ТекущаяДата();
ДокЗаказ.ЮКОЗ_НомерКПИзСайта = НомерКП;
ДокЗаказ.Приоритет = ПриоритетСредний;
ДокЗаказ.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.РеализацияКлиенту;
ДокЗаказ.ЦенаВключаетНДС = Истина;
ДокЗаказ.НалогообложениеНДС = Перечисления.ТипыНалогообложенияНДС.ПродажаОблагаетсяНДС;
ДокЗаказ.НомерПоДаннымКлиента = НомерКП;
ДокЗаказ.ДатаПоДаннымКлиента = ДатаКП;
ДокЗаказ.Склад = СкладОсновной;
ДокЗаказ.Статус = Перечисления.СтатусыЗаказовКлиентов.КОтгрузке;
ДокЗаказ.ЮКОЗ_Статус = Перечисления.ЮКОЗ_СтатусыЗаказовКлиентов.Согласование;
ДокЗаказ.Валюта = ВалютаДок;
ДокЗаказ.Соглашение = ТиповоеСоглашение;
ДокЗаказ.НеОтгружатьЧастями = Истина;
ДокЗаказ.ПорядокОплаты = Перечисления.ПорядокОплатыПоСоглашениям.РасчетыВВалютеОплатаВВалюте;
ДокЗаказ.ФормаОплаты = Перечисления.ФормыОплаты.Безналичная;
КонецЕсли;
//Очистим табличную часть Товары (на тот случай, если заказ клиента уже был ранее создан и там были какие-то данные)
ДокЗаказ.Товары.Очистить();
//Обходим данные из файла через нашу таблицу значений
Для каждого стр из ДанныеИзФайлаТовары Цикл
//Проверям на заполнение обязательный полей (артикул, производитель, номенклатура), если хоть что-то не заполнено, то вызываем ошибку с пояснением
Если НЕ ЗначениеЗаполнено(стр.Артикул) И НЕ ЗначениеЗаполнено(стр.ИД) Тогда
ВызватьИсключение "Пустой артикул и ID по КП " + НомерКП;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(стр.Производитель) Тогда
ВызватьИсключение "Пустой производитель по КП " + НомерКП;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(стр.Номенклатура) Тогда
ВызватьИсключение "Пустая номенклатура по КП " + НомерКП;
КонецЕсли;
//Пытаемся найти уже созданную номенклатуру по артикулу, а если он не заполнен, то по ИД.
ЗапросСущТовара = Новый Запрос();
ЗапросСущТовара.УстановитьПараметр("ИД", стр.ИД);
ЗапросСущТовара.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ" + Символы.ПС;
Если ЗначениеЗаполнено(стр.Артикул) Тогда
ЗапросСущТовара.Текст = ЗапросСущТовара.Текст + "Номенклатура.Артикул = &Артикул";
Иначе
ЗапросСущТовара.Текст = ЗапросСущТовара.Текст + "Номенклатура.ЮКОЗ_IDИзСайта = &ИД";
КонецЕсли;
Результат_ЗапросСущТовара = ЗапросСущТовара.Выполнить().Выбрать();
//Формируем представление строки описания номенклатуры (строковая характеристика)
ДобТоварЮКОЗ_Характеристика = ?(ЗначениеЗаполнено(стр.Серия), стр.Серия + ", ", "") +
?(ЗначениеЗаполнено(стр.Размер), стр.Размер + ", ", "") +
?(ЗначениеЗаполнено(стр.Цвет), стр.Цвет, "");
//Получаем ссылку на номенклатуру если она найдена
Если Результат_ЗапросСущТовара.Следующий() Тогда
ТоварСсылка = Результат_ЗапросСущТовара.Ссылка;
//Если номенклатура не найдена, то создаем её
Иначе
ТоварНовый = Справочники.Номенклатура.СоздатьЭлемент();
//Каждая номенлатура должна находится в своей группе в справочнике номенклатура, где название группы - это наименование производителя
//проверяем это запросом
ЗапросСущГруппы = Новый Запрос();
ЗапросСущГруппы.УстановитьПараметр("Производитель", стр.Производитель);
ЗапросСущГруппы.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Наименование = &Производитель
| И Номенклатура.ЭтоГруппа";
Результат_ЗапросСущГруппы = ЗапросСущГруппы.Выполнить().Выбрать();
//Если группа найдено, то берем ссылку на неё
Если Результат_ЗапросСущГруппы.Следующий() Тогда
ГруппаТовараСсылка = Результат_ЗапросСущГруппы.Ссылка;
//Если группа не найдена, то создаем её
Иначе
ГруппаТовараСсылка = Справочники.Номенклатура.СоздатьГруппу();
ГруппаТовараСсылка.Наименование = стр.Производитель;
ГруппаТовараСсылка.Записать();
ГруппаТовараСсылка = ГруппаТовараСсылка.Ссылка;
КонецЕсли;
//Указываем, что номенклатуру мы создаем в группе которую нашли\создали чуть ранее
ТоварНовый.Родитель = ГруппаТовараСсылка;
//Формируем представление наименования номенклатуры, оно должно содержать артикул, а если его нет, то ИД
//Также записываем артикул, если его нет, то ИД вместо него.
Если ЗначениеЗаполнено(стр.Артикул) Тогда
ТоварНовый.Артикул = стр.Артикул;
ТоварНовый.Наименование = Строка(?(ЗначениеЗаполнено(стр.Артикул), "(" + стр.Артикул + ") ", "") + стр.Номенклатура);
Иначе
ТоварНовый.Наименование = Строка(?(ЗначениеЗаполнено(стр.ИД), "(" + стр.ИД + ") ", "") + стр.Номенклатура);
ТоварНовый.Артикул = стр.ИД;
КонецЕсли;
//Добавляем в наименование номенклатуры строковое описание номенклатуры, которое мы сформировали ранее,
//при условии, что описание номенклатуры есть и оно уже не встречается в наименовании номенклатуры
Если ЗначениеЗаполнено(ДобТоварЮКОЗ_Характеристика) Тогда
Если СтрНайти(СтрЗаменить(ТоварНовый.Наименование, ",", ""),
СтрЗаменить(ДобТоварЮКОЗ_Характеристика, ",", "")) = 0 Тогда
ТоварНовый.Наименование = ТоварНовый.Наименование + ", " + ДобТоварЮКОЗ_Характеристика;
КонецЕсли;
КонецЕсли;
//Заполняем остальные поля номенклатуры
ТоварНовый.ЮКОЗ_IDИзСайта = стр.ИД;
ТоварНовый.ТипНоменклатуры = Перечисления.ТипыНоменклатуры.Товар;
ТоварНовый.ВидНоменклатуры = ВидНоменклатуры;
ТоварНовый.НаименованиеПолное = стр.Номенклатура + ?(ЗначениеЗаполнено(ДобТоварЮКОЗ_Характеристика),
", " + ДобТоварЮКОЗ_Характеристика, "");
ТоварНовый.СтавкаНДС = Перечисления.СтавкиНДС.НДС20;
ТоварНовый.ЕдиницаИзмерения = ЕдиницаИзмШТ;
ТоварНовый.ЕдиницаДляОтчетов = ЕдиницаИзмШТ;
ТоварНовый.ИспользованиеХарактеристик = Перечисления.ВариантыИспользованияХарактеристикНоменклатуры.НеИспользовать;
ТоварНовый.ВариантОформленияПродажи = Перечисления.ВариантыОформленияПродажи.РеализацияТоваровУслуг;
//Ищем производителя, если его нет, то создаем нового и указываем его в номенклатуре
ПроизводительСсылка = Справочники.Производители.НайтиПоНаименованию(стр.Производитель);
Если НЕ ЗначениеЗаполнено(ПроизводительСсылка) Тогда
НовыйПроизводитель = Справочники.Производители.СоздатьЭлемент();
НовыйПроизводитель.Наименование = стр.Производитель;
НовыйПроизводитель.Записать();
ПроизводительСсылка = НовыйПроизводитель.Ссылка;
КонецЕсли;
ТоварНовый.Производитель = ПроизводительСсылка;
//Записываем новую номенклатуру и получаем ссылку на неё
ТоварНовый.Записать();
ТоварСсылка = ТоварНовый.Ссылка;
КонецЕсли;
//Добавляем в табличную часть Товары номенклатуру с заполнением данных из файла xml
ДобТовар = ДокЗаказ.Товары.Добавить();
ДобТовар.Номенклатура = ТоварСсылка;
ДобТовар.Количество = стр.Количество;
ДобТовар.КоличествоУпаковок = стр.Количество;
ДобТовар.Упаковка = ДобТовар.Номенклатура.ЕдиницаИзмерения;
ДобТовар.Цена = стр.Цена;
ДобТовар.СтавкаНДС = ДобТовар.Номенклатура.СтавкаНДС;
ДобТовар.Склад = СкладОсновной;
ДобТовар.ЮКОЗ_Характеристика = ДобТоварЮКОЗ_Характеристика;
//Вычисляем процент ручной скидки, если в файле xml была указана цена со скидкой и она меньше, чем обычная цена
Если ЗначениеЗаполнено(стр.ЦенаСоСкидкой) И ЗначениеЗаполнено(стр.Цена) Тогда
стрЦенаСоСкидкой = Число(стр.ЦенаСоСкидкой);
стрЦена = Число(стр.Цена);
Если стрЦенаСоСкидкой > 0 И стрЦена > 0 И стрЦена > стрЦенаСоСкидкой Тогда
ДобТовар.ПроцентРучнойСкидки = (стрЦенаСоСкидкой / стрЦена - 1) * 100 * -1;
КонецЕсли;
КонецЕсли;
КонецЦикла;
//Посчитаем сумму строки, а также НДС
СтруктураПересчетаСуммы = ОбработкаТабличнойЧастиКлиентСервер.ПараметрыПересчетаСуммыНДСВСтрокеТЧ(ДокЗаказ);
СтруктураДействий = Новый Структура;
СтруктураДействий.Вставить("ПересчитатьСумму", "КоличествоУпаковок");
СтруктураДействий.Вставить("ПересчитатьСуммуНДС", СтруктураПересчетаСуммы);
СтруктураДействий.Вставить("ПересчитатьСуммуСНДС", СтруктураПересчетаСуммы);
ОбработкаТабличнойЧастиСервер.ОбработатьТЧ(ДокЗаказ.Товары, СтруктураДействий, Неопределено);
//Запишем заказ клиента без проведения
ДокЗаказ.Записать(РежимЗаписиДокумента.Запись);
//Обработаем исключения в блоке попытки с записью в журнал регистрации для дальнейшего анализа
Исключение
ЗаписьЖурналаРегистрации("Ошибка обработки КП из сайта: " + ОписаниеОшибки(), УровеньЖурналаРегистрации.Ошибка);
КонецПопытки;
КонецЦикла;
//После обработки всех файлов, закроем FTP соединение.
ФТПСоединение = Неопределено;
КонецПроцедуры
НаименованиеЗадания = НСтр("ru = 'Заполнение документа ""Начисление зарплаты""'");
Результат = ДлительныеОперации.ЗапуститьВыполнениеВФоне(
УникальныйИдентификатор,
"Документы.НачислениеЗаПервуюПоловинуМесяца.ПодготовитьДанныеДляЗаполнения",
СтруктураПараметров,
НаименованиеЗадания);
НаименованиеЗадания = НСтр("ru = 'Заполнение документа ""Начисление зарплаты""'");
Результат = ДлительныеОперации.ЗапуститьВыполнениеВФоне(
УникальныйИдентификатор,
"Документы.НачислениеЗаПервуюПоловинуМесяца.ПодготовитьДанныеДляЗаполнения",
СтруктураПараметров,
НаименованиеЗадания);