Почему обработчик "После загрузки" не срабатывает для новых элементов справочника при обмене ЗУП-БУХ через Конвертацию данных 2.0?

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

При работе с обменом данными между конфигурациями, например, ЗУП и БУХ, с использованием механизма "Конвертация данных 2.0", разработчики часто сталкиваются с необходимостью доработки стандартных правил. Одна из распространенных задач — это обработка создания и обновления элементов справочников в приемнике, особенно когда требуется выполнить дополнительную логику после загрузки данных. В этой статье мы подробно рассмотрим ситуацию, когда обработчик "После загрузки" не срабатывает для новых элементов справочника, и предложим решение.

Представим типовую задачу: из конфигурации "1С:Зарплата и Управление Персоналом" в "1С:Бухгалтерия" выгружается доработанный документ "ОтражениеЗарплатыВБухУчете". Этот документ имеет дополнительную табличную часть, в которой есть колонка "Начисления", представляющая собой ссылку на справочник. Наша цель — обеспечить корректную выгрузку значений из этого справочника в "1С:Бухгалтерия".

Особенность этой задачи заключается в том, что поиск элемента справочника в базе-приемнике осуществляется не по стандартной ссылке, а по пользовательскому реквизиту Кодификатор. Кроме того, наименования этих начислений в "1С:Бухгалтерия" должны соответствовать значениям из другого справочника, например, Справочники.СтатьиОборотов. То есть, если начисления нет в приемнике, его необходимо создать, но его наименование следует взять из уже существующего элемента справочника СтатьиОборотов, найденного по тому же Кодификатор.

Для реализации этой логики обычно используется обработчик "После загрузки" в Правилах Конвертации Объектов (ПКО) для целевого справочника. Код, который мы могли бы написать, выглядит примерно так:


// В обработчике "После загрузки" ПКО для справочника, например, "НачисленияБУХ"
Если Не Объект.Ссылка.Пустая() Тогда // Для существующих элементов
    // Логика для существующих, если нужна
Иначе // Для новых элементов
    НайденнаяСтатья = Справочники.СтатьиОборотов.НайтиПоРеквизиту("Кодификатор", Объект.Кодификатор);
    Если НайденнаяСтатья <> Неопределено Тогда
        Объект.Наименование = НайденнаяСтатья.Наименование;
    КонецЕсли;
КонецЕсли;

Однако, как показывает практика и обсуждаемая ситуация, при попытке выполнить подобный код, мы можем столкнуться с проблемой: элемент справочника в приемнике создается, реквизит Кодификатор заполняется, но его наименование остается пустым. При этом другие части обмена работают штатно. Это означает, что обработчик либо не срабатывает вовсе, либо срабатывает не так, как ожидалось для новых элементов.

Диагностика и выявление корневой причины

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


// В обработчике "После загрузки"
Объект.Наименование = "ТЕСТ_" + Строка(Новый УникальныйИдентификатор());
// или
Сообщить("Обработчик 'После загрузки' сработал для объекта " + Объект.Кодификатор);

Если даже такая "рандомная" запись наименования не срабатывает, это прямо указывает на то, что код в обработчике "После загрузки" либо не достигается, либо выполняется в неподходящем контексте для новых объектов.

В нашем случае, после тщательной диагностики, выяснилось, что корневая проблема заключалась в том, что целевой справочник (например, Справочники.НачисленияБУХ или Справочники.СтатьиОборотов, если он является целевым для создания элементов) не был включен в план обмена (его состав). Несмотря на то, что сам обмен проходил, и данные выгружались, события, связанные с этим справочником, не отрабатывали должным образом в приемнике.

Решение проблемы: Включение справочника в план обмена

Ключевым шагом к решению проблемы стало добавление справочника, который мы пытаемся модифицировать или создавать, в состав плана обмена. Давайте разберем этот процесс подробнее:

  1. Откройте конфигурацию "1С:Бухгалтерия" (базу-приемник) в режиме Конфигуратора.

  2. Перейдите к объекту "Планы обмена". В дереве объектов конфигурации найдите ветку "Планы обмена" и откройте тот план обмена, который используется для синхронизации с ЗУП (например, Полный или специализированный план, если такой есть).

  3. Отредактируйте состав плана обмена. Откройте форму объекта "План обмена". На вкладке "Состав" перечислены все объекты конфигурации (справочники, документы, регистры и т.д.), которые участвуют в обмене. Необходимо убедиться, что справочник, для которого мы дорабатывали логику в "После загрузки" (в нашем случае это мог быть Справочники.Начисления, если это новый справочник, или Справочники.СтатьиОборотов, если мы напрямую их создаем), включен в этот состав.

    • Если справочника нет в списке, добавьте его, установив соответствующий флажок.
    • Сохраните изменения в конфигурации базы данных.

После того как справочник был включен в состав плана обмена, обработчик "После загрузки" начал корректно отрабатывать для вновь создаваемых элементов, и наименования стали устанавливаться в соответствии с заданной логикой.

Дополнительные рекомендации и подходы

Помимо основного решения, давайте рассмотрим другие важные аспекты и альтернативные подходы, которые могут быть полезны при доработке обменов в "Конвертации данных 2.0".

1. Проверка заполненности реквизита "Кодификатор"

Прежде чем выполнять поиск по реквизиту, убедитесь, что Объект.Кодификатор действительно заполнен. Если Кодификатор не выгружается или не загружается, поиск по нему будет бессмысленным. Проверьте правила конвертации свойств (ПКС), чтобы удостовериться, что реквизит Кодификатор корректно передается из источника в приемник.

2. Использование других обработчиков событий

Механизм "Конвертации данных 2.0" предоставляет несколько обработчиков событий, каждый из которых выполняется на определенном этапе жизненного цикла объекта при обмене. Если "После загрузки" не дает желаемого результата (особенно для сложных сценариев или когда нужен более ранний доступ к данным), рассмотрите следующие:

  1. При загрузке: Этот обработчик выполняется раньше, чем "После загрузки". В нем вы можете попытаться предварительно найти существующий элемент по Кодификатору и, если он найден, установить его как объект для загрузки (переменная Объект), тем самым предотвратив создание нового дубля. Или же подготовить данные для дальнейшего использования в "После загрузки".

  2. Перед записью объекта: Этот обработчик выполняется непосредственно перед записью объекта в базу данных. В этот момент объект уже создан в памяти, и все его реквизиты (включая Кодификатор) должны быть заполнены. Это может быть более подходящий момент для установки наименования, если "После загрузки" по каким-то причинам не подходит.

    
    // В обработчике "Перед записью объекта" ПКО
    Если Объект.Наименование = "" Тогда // Проверяем, что наименование еще не установлено
        НайденнаяСтатья = Справочники.СтатьиОборотов.НайтиПоРеквизиту("Кодификатор", Объект.Кодификатор);
        Если НайденнаяСтатья <> Неопределено Тогда
            Объект.Наименование = НайденнаяСтатья.Наименование;
        КонецЕсли;
    КонецЕсли;
    
  3. Обработчики в Правилах Конвертации Свойств (ПКС): Если Кодификатор выгружается как свойство, можно в обработчике "При загрузке" этого свойства выполнить поиск и присвоить наименование. Это позволяет привязать логику к конкретному реквизиту.

3. Отладка обработчиков

Отладка — это критически важный этап при работе с обменами. "Конвертация данных" предоставляет несколько инструментов для этого:

  1. "Сформировать модуль отладки": Внутри обработки "Конвертация данных" есть возможность сформировать модуль отладки выгрузки/загрузки. Сформированные обработчики и алгоритмы выводятся в отдельное окно или файл. Это позволяет увидеть полный код, который будет выполняться.

  2. Внешняя обработка для отладки: Код модуля отладки можно скопировать в буфер обмена и вставить в модуль объекта внешней обработки в базе-приемнике. Затем, запустив универсальный обмен данными в режиме отладки и установив точку останова в нужной строке, мы можем пошагово отследить выполнение кода. Это позволяет видеть значения всех переменных в реальном времени.

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

4. Проверка корректности поиска

Убедитесь, что метод Справочники.СтатьиОборотов.НайтиПоРеквизиту("Кодификатор", Объект.Кодификатор) действительно возвращает корректную ссылку на существующий элемент. Если он возвращает пустую ссылку (Неопределено), это означает, что элемент не был найден. Причины могут быть разные:

5. Длина наименования и кода

Убедитесь, что длина наименования в справочнике-приемнике достаточна для записываемых значений. Недостаточная длина может привести к усечению или некорректной записи наименования без выдачи явной ошибки, что может запутать при отладке.

6. Уникальность идентификаторов

При создании новых объектов крайне важно, чтобы ключи поиска были заданы корректно и были уникальными. Если для идентификации элементов используется Кодификатор, он должен быть уникальным в целевом справочнике, чтобы избежать появления дубликатов.

7. Внешние обработки как библиотеки

Для реализации сложной логики, которая используется в нескольких местах или требует большого объема кода, целесообразно использовать подключаемые внешние обработки как библиотеки экспортируемых процедур/функций. Вы можете вызывать эти функции из обработчиков событий правил обмена. Это помогает избежать перегрузки кода непосредственно в правилах конвертации, делает его более модульным, читаемым и удобным для поддержки и отладки.

Например, вы можете создать внешнюю обработку с функцией:


// В модуле внешней обработки
Функция ПолучитьНаименованиеСтатьиПоКодификатору(Кодификатор) Экспорт
    НайденнаяСтатья = Справочники.СтатьиОборотов.НайтиПоРеквизиту("Кодификатор", Кодификатор);
    Если НайденнаяСтатья <> Неопределено Тогда
        Возврат НайденнаяСтатья.Наименование;
    Иначе
        Возврат ""; // или другое значение по умолчанию
    КонецЕсли;
КонецФункции

Затем в обработчике ПКО можно будет вызвать эту функцию:


// В обработчике "После загрузки" ПКО
Если Не Объект.Ссылка.Пустая() Тогда
    // Логика для существующих
Иначе
    Обработка = ВнешниеОбработки.Создать("ПутьКВнешнейОбработке.epf"); // Укажите реальный путь
    Объект.Наименование = Обработка.ПолучитьНаименованиеСтатьиПоКодификатору(Объект.Кодификатор);
КонецЕсли;

Заключение

Механизм обработчиков событий в "Конвертации данных 2.0" предоставляет мощные возможности для тонкой настройки обмена. Однако для его корректной работы, особенно при создании новых элементов справочников и поиске по пользовательским реквизитам, требуется внимательная настройка и, возможно, глубокая отладка. Как мы убедились, одной из самых неочевидных причин неработоспособности может быть простая невключенность объекта метаданных в план обмена. Всегда начинайте диагностику с проверки состава плана обмена и последовательно двигайтесь к отладке кода обработчиков. Используя описанные подходы и инструменты, вы сможете эффективно решать подобные задачи и обеспечивать надежный обмен данными между конфигурациями 1С.

← На главную