При проектировании правил обмена в конфигурации «Конвертация данных 2.1» (КД 2.1) разработчики часто сталкиваются с необходимостью разделить один хозяйственный документ из базы-источника на два независимых документа в базе-приемнике. Классический пример — перенос кадровых данных из ЗУП в УПП или ERP, когда один документ ПриемНаРаботу должен создать в приемнике как управленческий документ ПриемНаРаботу, так и регламентированный ПриемНаРаботуВОрганизацию.
На первый взгляд задача кажется простой: достаточно создать два Правила конвертации объектов (ПКО) и два Правила выгрузки данных (ПВД). Однако при стандартном подходе разработчики сталкиваются с тем, что выгружается только один документ, либо один документ полностью перезаписывает второй. В этой статье мы подробно разберем, почему так происходит, и рассмотрим два надежных метода решения этой проблемы.
Для того чтобы успешно решить задачу, нам необходимо понять внутренние механизмы работы платформы 1С при обмене данными. Существуют две фундаментальные причины, по которым стандартный подход дает сбой:
Выяснив причины, перейдем к рассмотрению двух профессиональных способов реализации этой задачи.
Это наиболее гибкий, контролируемый и рекомендуемый метод. Суть его заключается в том, что мы создаем одно основное ПВД для первого документа, а выгрузку второго документа инициируем принудительно из кода обработчика первого правила.
Рассмотрим по шагам, как настроить этот процесс:
Шаг 1. Создание ПКО и ПВД.
Создадим ПКО №1 (например, ПриемНаРаботу) и ПКО №2 (ПриемНаРаботуВОрганизацию). ПВД (Правило выгрузки данных) создаем только для ПКО №1. ПВД для второго правила создавать не нужно — мы будем вызывать его программно.
Шаг 2. Написание кода выгрузки в ПКО №1.
Откроем ПКО №1 и перейдем в обработчик событий ПослеВыгрузкиОбъекта (или ПослеВыгрузки). Использовать событие ПередВыгрузкой крайне не рекомендуется, так как это может привести к нарушению последовательности выгрузки ссылочных данных или бесконечной рекурсии.
Пропишем в обработчике следующий код для подготовки данных и вызова второго правила:
// Проверим дополнительное условие (например, по конкретной организации)
Если Источник.Организация.Наименование = "МояОрганизация" Тогда
// Создаем таблицу значений для передачи табличной части во второй документ
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Сотрудник");
ТЗ.Колонки.Добавить("Подразделение");
ТЗ.Колонки.Добавить("Должность");
ТЗ.Колонки.Добавить("ГрафикРаботы");
ТЗ.Колонки.Добавить("ДатаПриема");
ТЗ.Колонки.Добавить("КоличествоСтавок");
// Заполняем строку таблицы данными из источника
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Sотрудник = Источник.Сотрудник;
НоваяСтрока.Подразделение = Источник.Подразделение;
НоваяСтрока.Должность = Источник.ДолжностьПоШтатномуРасписанию;
НоваяСтрока.ГрафикРаботы = Источник.ГрафикРаботы;
НоваяСтрока.ДатаПриема = Источник.ДатаПриема;
НоваяСтрока.КоличествоСтавок = Источник.КоличествоСтавок;
// Помещаем таблицу во входящие данные
ПараметрыВторогоДокумента = Новый Структура;
ПараметрыВторогоДокумента.Вставить("Работники", ТЗ);
// Вызываем программную выгрузку по второму правилу конвертации
ВыгрузитьПоПравилу(Источник, , ПараметрыВторогоДокумента, , "ПриемНаРаботуВОрганизацию");
КонецЕсли;
Разберем параметры функции ВыгрузитьПоПравилу:
Шаг 3. Настройка ПКО №2 для приема входящих данных.
Во втором ПКО для всех свойств (ПКС) и табличных частей, которые мы передаем через структуру ПараметрыВторогоДокумента, необходимо установить флаг «Получить из входящих данных». Это укажет системе, что данные нужно брать не непосредственно из объекта-источника, а из переданной нами структуры.
Если по каким-то причинам вы хотите использовать стандартные Правила выгрузки данных для обоих документов (например, чтобы иметь возможность интерактивно регистрировать их к узлам плана обмена отдельно друг от друга), вам потребуется решить проблему кэширования платформы.
Для этого используется специальный параметр КлючВыгружаемыхДанных. Он определяет уникальность выгружаемой записи в рамках сеанса работы выгрузки.
Проанализируем шаги реализации этого метода:
Шаг 1. Настройка обработчика ПКО №1.
В ПКО №1 («ПриемНаРаботу») в обработчике события ПередВыгрузкой пишем код:
КлючВыгружаемыхДанных = "ПриемНаРаботу_" + СокрЛП(Источник.УникальныйИдентификатор());
Шаг 2. Настройка обработчика ПКО №2.
В ПКО №2 («ПриемНаРаботуВОрганизацию») в обработчике события ПередВыгрузкой задаем другой уникальный префикс:
КлючВыгружаемыхДанных = "ПриемНаРаботуВОрганизацию_" + СокрЛП(Источник.УникальныйИдентификатор());
Благодаря этому приеме КД 2.1 перестанет считать эти объекты дублями и выгрузит оба документа в файл обмена в полном объеме.
Даже решив проблему кэша на этапе выгрузки, мы можем столкнуться с тем, что в базе-приемнике один документ перезапишет другой из-за совпадения УИД. Чтобы этого не произошло, необходимо перенастроить правила поиска для второго документа:
ПриемНаРаботуВОрганизацию) в Конвертации данных.Номер, Дата, Организация) установите флаг «Поиск».ПоляПоиска ПКО №2, чтобы система могла однозначно идентифицировать документ в приемнике при повторных обменах, не используя УИД.Таким образом, мы исключим коллизию идентификаторов, и в базе-приемнике успешно создадутся два разных, независимых документа.
Мы подробно разобрали, как решить задачу выгрузки одного документа в два разных приемника. Выбор метода зависит от ваших архитектурных требований: метод с ВыгрузитьПоПравилу() является более гибким и рекомендуется в большинстве случаев, тогда как метод с КлючВыгружаемыхДанных незаменим при раздельной регистрации объектов на планах обмена.