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