При настройке обмена данными между конфигурациями (например, 1С:Управление торговлей 11 и 1С:Бухгалтерия предприятия 3.0) через Конвертацию данных 2.1 нередко возникает задача: передавать документы только тогда, когда наступает фактическая дата документа (документы, выписанные на будущее число, не должны сразу попадать в бухгалтерскую базу). Однако при добавлении простого условия отмены выгрузки в обработчики разработчики сталкиваются с тем, что документ исключается из текущего файла, но платформа снимает его с регистрации изменений. В результате при наступлении нужной даты документ повторно не выгружается.
Разберем подробно, почему так происходит и какими способами можно реализовать корректную отложенную выгрузку.
Выясним причину такого поведения платформы 1С:
Отказ = Истина; в обработчиках ПВД («Перед выгрузкой данных») или ПКО («Перед выгрузкой») лишь предотвращает запись объекта в XML-файл выгрузки. Это действие не возвращает объект в список изменений и не сообщает платформе о необходимости сохранить регистрацию на узле.Рассмотрим самый быстрый способ решения задачи непосредственно внутри правил конвертации данных. Если документ не проходит по условию даты, мы отменяем его выгрузку и сразу же повторно регистрируем его изменение на текущем узле обмена.
В обработчике ПВД («Перед выгрузкой данных») или ПКО («Перед выгрузкой») пишем следующий код:
Если Источник.Дата > ТекущаяДата() Тогда
Отказ = Истина;
ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, Источник.Ссылка);
КонецЕсли;
Проанализируем работу этого алгоритма:
ПланыОбмена.ЗарегистрироватьИзменения заново помещает ссылку в таблицу изменений узла, но уже со следующим номером сообщения.Обратите внимание: данный способ создает небольшую избыточную нагрузку при частых сеансах обмена, так как непрошедшие документы регистрируются заново в каждом цикле.
Разберем вариант, когда в Правиле выгрузки данных (ПВД) переопределяется стандартная выборка. Для этого в свойствах ПВД переключаем режим на Произвольный запрос и формируем данные вручную в обработчике Перед обработкой.
В этом случае мы можем напрямую обратиться к виртуальной таблице изменений документа и сразу наложить условие по дате:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТаблицаИзменений.Ссылка КАК Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг.Изменения КАК ТаблицаИзменений
|ГДЕ
| ТаблицаИзменений.Узел = &УзелОбмена
| И ТаблицаИзменений.Ссылка.Дата <= &ТекущаяДата";
Запрос.УстановитьПараметр("УзелОбмена", УзелОбмена);
Запрос.УстановитьПараметр("ТекущаяДата", КонецДня(ТекущаяДата()));
ВыборкаДанных = Запрос.Выполнить().Выгрузить();
Посмотрим на нюанс этого решения: если типовой механизм БСП производит автоматическое удаление регистрации для всех переданных сообщений через метод ПланыОбмена.ВыбратьИзменения, документы с будущей датой, которые не вошли в выборку запроса, останутся в таблице регистрации до наступления нужного дня, если для них не был сформирован номер сообщения.
Разберем наиболее архитектурно правильный подход для высоконагруженных систем:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Реализация.Ссылка КАК Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
| Реализация.Проведен = ИСТИНА
| И Реализация.Дата МЕЖДУ &НачалоДня И &КонецДня";
Запрос.УстановитьПараметр("НачалоДня", НачалоДня(ТекущаяДата()));
Запрос.УстановитьПараметр("КонецДня", КонецДня(ТекущаяДата()));
Выборка = Запрос.Выполнить().Выбрать();
МассивСсылок = Новый Массив;
Пока Выборка.Следующий() Цикл
МассивСсылок.Добавить(Выборка.Ссылка);
КонецЦикла;
Если МассивСсылок.Количество() > 0 Тогда
ПланыОбмена.ЗарегистрироватьИзменения(УзелБухгалтерия, МассивСсылок);
КонецЕсли;
Такой подход полностью исключает холостые прогоны правил обмена и обеспечивает гарантированную передачу документов день в день.