Как настроить перенос данных из независимого регистра сведений в документ при обмене между УНФ и Бухгалтерией 3.0

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При настройке нетипового обмена данными между конфигурациями «1С:Управление нашей фирмой» (УНФ) и «1С:Бухгалтерия предприятия» (БП) разработчики часто сталкиваются с архитектурным несовпадением структур хранения данных. Классический пример — необходимость перенести информацию о ценах. В УНФ цены хранятся в плоской структуре независимого периодического регистра сведений ЦеныНоменклатуры, тогда как в БП 3.0 установка цен оформляется одноименным документом УстановкаЦенНоменклатуры, содержащим шапку (дата, тип цен) и табличную часть (товары и цены).

В этой статье мы подробно разберем, как решить эту задачу с помощью программного пакета «Конвертация данных 2.1». Мы изучим алгоритм группировки данных, правила настройки ПКО, механизмы регистрации изменений независимых регистров и предотвращение дублирования документов в базе-приемнике.

---

Шаг 1. Группировка данных в ПВД (Правила выгрузки данных)

Поскольку в источнике данные представлены плоскими записями, а в приемнике требуется создать документ, стандартный перенос «один в один» не сработает. Нам необходимо предварительно сгруппировать записи регистра по дате (в пределах дня) и по виду цен, сформировать из них «виртуальный» документ в виде структуры и передать его на выгрузку.

Для этого в Конвертации данных создадим ПВД для документа УстановкаЦенНоменклатуры. Установим способ выборки данных — «Произвольный алгоритм». Напишем код в обработчике «Перед обработкой»:


// Запрос для выборки измененных цен и их группировки по дням и типам цен
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗЛИЧНЫЕ
    |	НАЧАЛОПЕРИОДА(Цены.Период, ДЕНЬ) КАК ДатаДокумента,
    |	Цены.ВидЦен КАК ВидЦен
    |ПОМЕСТИТЬ ВТ_Группы
    |ИЗ
    |	РегистрСведений.ЦеныНоменклатуры КАК Цены
    |// Здесь можно добавить фильтр по зарегистрированным изменениям, если это необходимо
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |	ВТ_Группы.ДатаДокумента КАК ДатаДокумента,
    |	ВТ_Группы.ВидЦен КАК ВидЦен,
    |	Цены.Номенклатура КАК Номенклатура,
    |	Цены.Цена КАК Цена
    |ИЗ
    |	ВТ_Группы КАК ВТ_Группы
    |		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК Цены
    |		ПО НАЧАЛОПЕРИОДА(Цены.Период, ДЕНЬ) = ВТ_Группы.ДатаДокумента
    |			И Цены.ВидЦен = ВТ_Группы.ВидЦен
    |ИТОГИ ПО
    |	ДатаДокумента,
    |	ВидЦен";

РезультатЗапроса = Запрос.Выполнить();

// Выборка по датам
ВыборкаДата = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "ДатаДокумента");
Пока ВыборкаДата.Следующий() Цикл
    
    // Выборка по видам цен внутри дня
    ВыборкаВидЦен = ВыборкаДата.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "ВидЦен");
    Пока ВыборкаВидЦен.Следующий() Цикл
        
        // Создаем структуру, имитирующую будущий документ
        ДанныеДокумента = Новый Структура;
        ДанныеДокумента.Вставить("Дата", ВыборкаВидЦен.ДатаДокумента);
        ДанныеДокумента.Вставить("ТипЦен", ВыборкаВидЦен.ВидЦен);
        
        // Создаем таблицу значений для будущей табличной части "Товары"
        ТаблицаТовары = Новый ТаблицаЗначений;
        ТаблицаТовары.Колонки.Добавить("Номенклатура");
        ТаблицаТовары.Колонки.Добавить("Цена");
        
        // Заполняем табличную часть конкретными позициями номенклатуры и ценами
        ВыборкаДетали = ВыборкаВидЦен.Выбрать();
        Пока ВыборкаДетали.Следующий() Цикл
            НоваяСтрока = ТаблицаТовары.Добавить();
            НоваяСтрока.Номенклатура = ВыборкаДетали.Номенклатура;
            НоваяСтрока.Цена         = ВыборкаДетали.Цена;
        КонецЦикла;
        
        ДанныеДокумента.Вставить("Товары", ТаблицаТовары);
        
        // Выгружаем подготовленную структуру по правилу конвертации объектов
        ВыгрузитьПоПравилу(,, ДанныеДокумента,, "УстановкаЦенНоменклатуры");
        
    КонецЦикла;
КонецЦикла;

---

Шаг 2. Настройка ПКО (Правила конвертации объектов)

Для того чтобы Конвертация данных корректно сопоставила поля нашей структуры с реквизитами документа в базе-приемнике, настроим ПКО для УстановкаЦенНоменклатуры следующим образом:

  1. Создаем ПКО, где Источник оставляем пустым, а Приемником указываем документ УстановкаЦенНоменклатуры.
  2. В таблице настроек свойств (ПКС) для реквизитов шапки (Дата, ТипЦен) и табличной части (Товары) обязательно взводим флаг «Получать из входящих данных».
  3. Для реквизитов внутри табличной части Товары (таких как Номенклатура и Цена) также включаем этот флаг. Названия колонок в нашей таблице значений внутри структуры должны строго совпадать с именами реквизитов табличной части документа-приемника.

---

Шаг 3. Настройка регистрации изменений для независимого регистра сведений

Как отмечалось в сообщениях форума, независимые регистры сведений часто имеют запрет на авторегистрацию в планах обмена конфигурации. Это делается разработчиками 1С намеренно для оптимизации производительности. Чтобы изменения по регистру ЦеныНоменклатуры попадали в узел обмена, необходимо задействовать механизмы БСП (Библиотеки стандартных подсистем).

Для этого в конфигурации-источнике используются Подписки на события:


ОбменДаннымиСобытия.ЗарегистрироватьИзмененияПередЗаписьюРегистра(Источник, Отказ, Замещение);

Этот метод автоматически определит, к каким планам обмена подключен данный регистр, проверит правила регистрации объектов (ПРО) и выполнит запись в таблицы изменений для соответствующих узлов.

Если вам требуется реализовать полностью ручную программную регистрацию в определенном месте вашего кода, вы можете воспользоваться методом ЗарегистрироватьИзменения менеджера планов обмена:


// Пример программной регистрации набора записей регистра
НаборЗаписей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Период.Установить(ТекущаяДата);
// ... установка других отборов ...
НаборЗаписей.Прочитать();

Если НаборЗаписей.Количество() > 0 Тогда
    ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, НаборЗаписей);
КонецЕсли;

Для визуальной проверки того, зарегистрированы ли изменения по регистру на узле обмена, рекомендуется использовать типовую обработку Регистрация изменений для обмена данными (доступна в составе подсистем БСП или на диске ИТС).

---

Шаг 4. Предотвращение дублирования документов в Бухгалтерии 3.0

При каждом запуске сеанса обмена выгружаемые из регистра цены за определенный день могут создать новый документ УстановкаЦенНоменклатуры в приемнике. Чтобы этого не происходило, нам нужно переопределить стандартный поиск по Уникальному Идентификатору (УИД) на поиск по ключевым полям: Дате и Типу цен.

В ПКО УстановкаЦенНоменклатуры откроем обработчик события «Поля поиска» и напишем следующий алгоритм:


Если СвойстваПоиска <> Неопределено Тогда
    
    // Выполняем поиск существующего документа за эту дату с таким же типом цен
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1
        |	УстановкаЦен.Ссылка КАК Ссылка
        |ИЗ
        |	Документ.УстановкаЦенНоменклатуры КАК УстановкаЦен
        |ГДЕ
        |	УстановкаЦен.Проведен = ИСТИНА
        |	И НАЧАЛОПЕРИОДА(УстановкаЦен.Дата, ДЕНЬ) = &Дата
        |	И УстановкаЦен.ТипЦен = &ТипЦен";
    
    // Приводим дату к началу дня, чтобы сопоставление было корректным
    Запрос.УстановитьПараметр("Дата", НачалоДня(СвойстваПоиска.Получить("Дата")));
    Запрос.УстановитьПараметр("ТипЦен", СвойстваПоиска.Получить("ТипЦен"));
    
    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        СсылкаНаОбъект = Выборка.Ссылка;
    КонецЕсли;
    
КонецЕсли;

При использовании такого подхода, если в базе-приемнике (БП 3.0) уже существует проведенный документ за указанную дату по данному типу цен, система не будет создавать новый элемент, а обновит табличную часть существующего документа актуальными ценами из источника.

Для автоматического вступления цен в силу, в обработчике ПКО «После загрузки» на стороне приемника можно прописать программное проведение загруженного документа:


Если Объект.Проведен = Ложь Тогда
    Попытка
        Объект.Записать(РежимЗаписиДокумента.Проведение);
    Исключение
        ЗаписьЖурналаРегистрации("ОбменДанными.ПроведениеЦен", 
            УровеньЖурналаРегистрации.Предупреждение,,, 
            ОписаниеОшибки());
    КонецПопытки;
КонецЕсли;

---

Заключение

Мы успешно разобрали сложную схему трансформации плоских данных регистра сведений в полноценный документ с табличной частью при помощи Конвертации данных 2.1. Использование произвольных алгоритмов выборки в ПВД в связке с правильной регистрацией изменений через подписки на события БСП гарантирует стабильный и контролируемый перенос цен между «1С:УНФ» и «1С:Бухгалтерия предприятия 3.0».

← На главную