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