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