При переносе начальных остатков по счетам взаиморасчетов с контрагентами (например, по счету 60 или 62) разработчики часто сталкиваются с ситуацией, когда в конфигурации-источнике (например, УПП 1.3) аналитический учет ведется только по контрагентам и договорам, а в конфигурации-приемнике (Бухгалтерия предприятия 2.0 или 3.0) на счете присутствует третье субконто — Документы расчетов с контрагентом. Возникает необходимость сформировать новый вспомогательный документ (например, Документ расчетов с контрагентом (ручной учет)) и корректно сослаться на него в строках табличной части документа Ввод начальных остатков.
Разберем типичные ошибки при реализации этой задачи в «Конвертации данных 2.0», проанализируем, почему не срабатывает прямой вызов функции ВыгрузитьПоПравилу, и рассмотрим правильные архитектурные решения.
Рассмотрим фрагмент кода, с которого обычно начинаются попытки решить проблему в обработчике Перед обработкой правила правила выгрузки данных (ПВД):
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Формируем структуру расчетного документа
ДРК = Новый Структура;
ДРК.Вставить("ВалютаДокумента", Выборка.Валюта);
ДРК.Вставить("Дата", ТекДата);
ДРК.Вставить("ДоговорКонтрагента", Выборка.Договор);
ДРК.Вставить("Контрагент", Выборка.Контрагент);
ДРК.Вставить("Организация", Выборка.Организация);
ДРК.Вставить("СуммаДокумента", Выборка.Сумма);
ВыгрузитьПоПравилу(, , ДРК, , "ДокументРасчетовСКонтрагентом");
НоваяСтрока = ТЧ.Добавить();
НоваяСтрока.Документ = ДРК;
КонецЦикла;
Шапка.Вставить("РасчетыСКонтрагентами", ТЧ);
ВыгрузитьПоПравилу(, , Шапка, , "ВводНачальныхОстатковРасчетыСКонтрагентами");
Выясним причину, почему данный подход работает некорректно:
ВыгрузитьПоПравилу выполняет сериализацию объекта в выходной XML-поток и не возвращает ссылку на объект в базе-приемнике. Присвоить результат вызова переменной невозможно.ВыгрузитьПоПравилу изолированно для структуры ДРК, в XML создается отдельный узел документа. При последующей передаче той же структуры в составе строки НоваяСтрока.Документ = ДРК механизм конвертации попытается выгрузить ее повторно. Поскольку у структуры нет постоянного уникального идентификатора (GUID ссылки), в базе-приемнике возникнет дублирование объектов либо появится битая ссылка со значением «Объект не найден».Если мы хотим решить задачу строго на этапе выгрузки данных без ручного дописывания логики на стороне приемника, следует доверить сопоставление штатным механизмам конвертации свойств.
Разберем по шагам, как настроить правила конвертации:
ВыгрузитьПоПравилу для вспомогательного документа. Мы просто помещаем сформированную структуру в поле строки табличной части:
Пока Выборка.Следующий() Цикл
ДРК = Новый Структура;
ДРК.Вставить("ВалютаДокумента", Выборка.Валюта);
ДРК.Вставить("Дата", ТекДата);
ДРК.Вставить("ДоговорКонтрагента", Выборка.Договор);
ДРК.Вставить("Контрагент", Выборка.Контрагент);
ДРК.Вставить("Организация", Выборка.Организация);
ДРК.Вставить("СуммаДокумента", Выборка.Сумма);
НоваяСтрока = ТЧ.Добавить();
// Помещаем структуру прямо в колонку табличной части:
НоваяСтрока.Субконто3 = ДРК;
// Заполняем остальные реквизиты строки
НоваяСтрока.СчетУчета = Выборка.Счет;
НоваяСтрока.Сумма = Выборка.Сумма;
КонецЦикла;
ДокументРасчетовСКонтрагентом, где в качестве источника оставляем пустое значение (объект без источника), а в качестве приемника выбираем документ ДокументРасчетовСКонтрагентом (или ручной учет).Проведен, ПометкаУдаления, Номер). Если этого не сделать, КД попытается прочитать их из переданной структуры и выдаст ошибку Поле объекта не обнаружено.Организация, Контрагент, ДоговорКонтрагента, Дата (или входящий номер/дата). Это исключит бесконечное дублирование документов при повторных строках.ВводНачальныхОстатков в табличной части для свойства, соответствующего третьему субконто (документу расчетов), в колонке Правило явно указываем наше ПКО ДокументРасчетовСКонтрагентом. Механизм КД сам обнаружит структуру, применит указанное правило и корректно свяжет объекты в XML-файле.Во многих типовых правилах переноса создание расчетных документов выносится на этап загрузки. Это исключает передачу избыточных структур через XML и упрощает контроль над итогами проведения.
Посмотрим, как это реализуется в обработчике ПослеЗагрузки ПКО документа ВводНачальныхОстатков:
// Обработчик "После загрузки" документа ВводНачальныхОстатков
Для Каждого СтрокаТЧ Из Объект.РасчетыСКонтрагентами Цикл
Если Не ЗначениеЗаполнено(СтрокаТЧ.ДокументРасчетов) Тогда
// Создаем новый вспомогательный расчетный документ программно
НовыйДок = Документы.ДокументРасчетовСКонтрагентом.СоздатьДокумент();
НовыйДок.Дата = Объект.Дата;
НовыйДок.Организация = Объект.Организация;
НовыйДок.Контрагент = СтрокаТЧ.Контрагент;
НовыйДок.ДоговорКонтрагента = СтрокаТЧ.ДоговорКонтрагента;
НовыйДок.СуммаДокумента = СтрокаТЧ.Сумма;
Попытка
НовыйДок.Записать(РежимЗаписиДокумента.Запись);
СтрокаТЧ.ДокументРасчетов = НовыйДок.Ссылка;
Исключение
ЗаписьЖурналаРегистрации("ПереносОстатков", УровеньЖурналаРегистрации.Ошибка, , ,
"Не удалось создать документ расчетов: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
Проанализируем типовую специфику плана счетов в конфигурации «Бухгалтерия предприятия». Тип субконто Документы расчетов с контрагентами является составным и включает в себя не только специализированный документ расчетов, но и сам документ Ввод начальных остатков.
Если детальная история по расчетным накладным в исходной базе не велась и вводить пустые документы расчетов нет необходимости, в качестве третьего субконто можно указать ссылку на текущий создаваемый документ ввода остатков. В таком случае в строке табличной части субконто заполняется ссылкой на сам загружаемый объект ввода остатков в обработчике ПослеЗагрузки через Объект.Ссылка.