Очень часто приходится делать/дорабатывать конвертации разного плана. В связи с этим появилось несколько шаблонов, решающих общие для всех обменов задачи, с которыми хотелось бы поделиться.
1. Интерактивное управление обменами.
Типовые обмены и большинство рукописных не позволяют интерактивно управлять правилами. Например, на время сдачи отчетности необходимо отключить в обмене несколько видов документов. Обычно это решают либо изменением правил регистрации либо изменением самих правил конвертации. Я на нескольких обменах сделал следующее:
- создал расширение, в котором заведен регистр сведений (непериодический, независимый) и перечисление (перечисление на самом деле не обязательно, можно например и строку использовать). Структура регистра на рис.
Измерение - ТипОбъекта (перечисление либо строка)
Ресурс - Выгружать (булево)
После этого в режиме предприятия заполняем флаги обмена.
Далее в самой конвертации:
//Перед выгрузкой данных
//Получаем список флагов на выгрузку
Запрос = Новый Запрос;
Запрос.Текст = "Выбрать
| УправлениеОбменомСБП.ТипОбъекта КАК ТипОбъекта,
| УправлениеОбменомСБП.Выгружать
|ИЗ РегистрСведений. УправлениеОбменомСБП КАК УправлениеОбменомСБП";
Выборка = Запрос.Выполнить().Выбрать();
тзОбъектов = Новый ТаблицаЗначений;
тзОбъектов.Колонки.Добавить("ТипОбъекта");
тзОбъектов.Колонки.Добавить("Выгружать");
Пока Выборка.Следующий() Цикл
нСтрока = тзОбъектов.Добавить();
нСтрока.ТипОбъекта = ВРег(СтрЗаменить(Выборка.ТипОбъекта, " ",""));
нСтрока.Выгружать = Выборка.Выгружать;
КонецЦикла;
Параметры.Вставить("тзОбъектовНаВыгрузку", тзОбъектов);
Теперь у нас есть таблица с описанием типа данных и флагом выгрузки.
Далее нам просто необходимо в обработчиках выгрузки добавить проверку.
//Начало определяем необходимость выгрузки
Выгружать = Ложь;
ОбъектМД = Объект.Метаданные();
ИмяОбъектаМД = ОбъектМД.Имя;
ИмяОбъекта = Врег(ИмяОбъектаМД);
НайденнаяСтрока =Параметры. тзОбъектовНаВыгрузку.Найти(ИмяОбъекта, "ТипОбъекта");
Если НайденнаяСтрока<>Неопределено Тогда
Выгружать = НайденнаяСтрока.Выгружать;
КонецЕсли;
Сообщить("выгружается " + ИмяОбъекта + "; "+ Выгружать);
//Конец определяем необходимость выгрузки
Если Выгружать Тогда
//тут выгрузки по различным условиям
Иначе
Отказ = Истина;
КонецЕсли;
Если флаг выгрузки не установлен, то делаем Отказ=Истина. При необходимости здесь же можно удалять объект с узла.
Таким образом, если нам нужно быстро отключить выгрузку некоторых типов объектов, мы в регистре просто устанавливаем значение Выгружать в Ложь.
2. Произвольное логирование обменов
Для того, чтобы собирать логи выгрузки и загрузки нам потребуется два массива строк. На примере выгрузки создаем массив пМассивЛогов и добавляем его в параметры.
Обработчик ПередВыгрузкойДанных
пМассивЛогов = Новый Массив;
Параметры.Вставить("пМассивЛогов", пМассивЛогов);
Далее в нужных обработчиках выгрузки формируем нужные нам сообщения, добавляем их в массив
СообщениеЛога - формируем некое сообщение
Параметры.пМассивЛогов.Добавить(СообщениеЛога);
В обработчике ПослеВыгрузкиДанных на основании массива делаем лог-файл в указанной папке.я указал папку жестко, но можно например завести константу в базе и путь к папке хранить там.
пМассивЛогов = Параметры.пМассивЛогов;
Если пМассивЛогов.Количество()>0 Тогда
ДатаВыгрузки = СтрЗаменить(СтрЗаменить(СтрЗаменить(Строка(ТекущаяДата()), ".","")," ", ""),":", "");
Каталог = "\\test\BP1C\log\";
Назначение = "Бп_Онли";
пИмяФайлаЛога = ""+ДатаВыгрузки+"_"+"ВыгрузкаВ_"+Назначение +".txt";
ПИмяФайлаЛогаПолное = Каталог+ пИмяФайлаЛога;
ТекстовыйФайл = Новый ТекстовыйДокумент;
Для Каждого строкаЛога Из пМассивЛогов Цикл
ТекстовыйФайл.ДобавитьСтроку(строкаЛога);
КонецЦикла;
ТекстовыйФайл.Записать(
ПИмяФайлаЛогаПолное, // путь для сохранения
КодировкаТекста.UTF8, // кодировка
Символы.ВК + Символы.ПС // разделитель строк
);
КонецЕсли;
В результате после выгрузки в указанной папке формируется файл лога. Для загрузки процедура такая же в принципе.
3. Проверка даты запрета
В обработчике Перед загрузкой данных получаем дату запрета для нужного списка пользователей (групп). В данном примере только для текущего пользователя, так как регламентное задание настроено с указанием конкретного пользователя, заведенного для обмена. Это также удобно, когда нужно найти что-то, связанное с обменом, в журнале регистрации.
//----------------ПРОВЕРКА ЗАКРЫТОГО ПЕРИОДА----------------------------------------------------
СписокПользователей = Новый СписокЗначений;
СписокПользователей.Добавить(ПараметрыСеанса.ТекущийПользователь);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДатыЗапретаИзменения.ДатаЗапрета
|ИЗ
| РегистрСведений.ДатыЗапретаИзменения КАК ДатыЗапретаИзменения
|ГДЕ
| ДатыЗапретаИзменения.Пользователь В (&Пользователь)";
Запрос.УстановитьПараметр("Пользователь", СписокПользователей);
РезультатЗапроса = Запрос.Выполнить().Выбрать();
Если РезультатЗапроса.Следующий() Тогда
ДатаЗапрета = РезультатЗапроса.ДатаЗапрета;
Сообщить("Дата запрета загрузки: " +ДатаЗапрета);
Иначе
ДатаЗапрета = Дата(1, 1, 1);
КонецЕсли;
Параметры.Вставить("ДатаЗапрета", КонецДня(ДатаЗапрета));
//-----------------------------------------------------------------------------------------------
В обработчике ПослеЗагрузки делаем проверку. Ниже пример обработчика для документа РеализацияТоваровУслуг (БП 3.0).
Если Объект.Дата<Параметры.ДатаЗапрета)Тогда
Отказ = Истина;
ОбъектМодифицирован = Ложь;
СообщениеЛога = "Дата объекта меньше разрешенной. Загрузка объекта " + Объект +" отменена!";
Параметры.пМассивЛоговЗагрузка.Добавить(СообщениеЛога);
Сообщить(СообщениеЛога);
Иначе
Отказ = Ложь;
Документы.РеализацияТоваровУслуг.ЗаполнитьСчетаУчетаРасчетов(Объект);
Документы.РеализацияТоваровУслуг.ЗаполнитьСчетаУчетаВТабличнойЧасти(Объект,"Товары");
Документы.РеализацияТоваровУслуг.ЗаполнитьСчетаУчетаВТабличнойЧасти(Объект,"Услуги");
Объект.Записать();
СтрокаТЗ = Параметры.ПроводимыеДокументы.Добавить();
СтрокаТЗ.Дата = Объект.Дата;
СтрокаТЗ.Документ = Объект.Ссылка;
КонецЕсли;
Если документ находится в закрытом периоде. происходит отказ от записи, в противном случае документ записывается/проводится.
4. Постобработка/проведение документов
Часто возникает необходимость в том, чтобы документы после загрузки провелись в определенной последовательности, либо перезаполнились с учетом данных базы (например проверка остатков и перезаполнение табличной части товаров в соответствие с ними). Для этих целей можно использовать следующий механизм.
В обработчике ПередЗагрузкойДанных заводим параметр типа ТаблицаЗначений
ПроводимыеДокументы = Новый ТаблицаЗначений;
ПроводимыеДокументы.Колонки.Добавить("Дата");
ПроводимыеДокументы.Колонки.Добавить("Документ");
ПроводимыеДокументы.Колонки.Добавить("Приоритет");
Параметры.Вставить("ПроводимыеДокументы", ПроводимыеДокументы);
Далее в обработчиках объектов ПослеЗагрузки добавляем
Объект.Записать();
СтрокаТЗ = Параметры.ПроводимыеДокументы.Добавить();
СтрокаТЗ.Дата = Объект.Дата;
СтрокаТЗ.Документ = Объект.Ссылка;
СтрокаТЗ. Приоритет = 0;
В обработчике ПослеЗагрузкиДанных
Параметры.ПроводимыеДокументы.Сортировать("Дата"); //либо по Приоритету
Для Каждого СтрокаТЗ ИЗ Параметры.ПроводимыеДокументы Цикл
пСсылкаТЧ = СтрокаТЗ.Документ;
Объект = пСсылкаТЧ.ПолучитьОбъект();
//Далее постобработка документа. дозаполнение, проверка.
КонецЦикла;
В обработчике, приведенном выше, можно делать различные операции с документом, а также в зависимости от условий делать проведение/отмену проведения. помечать на удаление и т.д.
При необходимости могу прикрепить пример рабочих правил, где данные методики использовались.