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