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