Почему не работает НайтиПоКоду в обработчике Перед загрузкой в Конвертации данных

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

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

Рассмотрим подробно причины такого поведения механизмов 1С:Конвертации данных и разберем правильные варианты архитектуры переноса данных.

Анализ проблемы: почему НайтиПоКоду возвращает пустую ссылку

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


СпрСтатьи = Справочники.СтатьиАналитикиОплатыЧекаККМ.СоздатьЭлемент();
СпрСтатьи.КПС = Справочники.КлассификационныеПризнакиСчетов.НайтиПоКоду("09050000000000130");
СпрСтатьи.КФО = Перечисления.КВД.Внебюджет;
СпрСтатьи.КЭК = Справочники.КОСГУ.НайтиПоКоду("130");
СпрСтатьи.Наименование = "Внебюджет";
СпрСтатьи.Организация = Справочники.Организации.НайтиПоКоду("000000001");
СпрСтатьи.Записать();

После выполнения этого кода элемент справочника создается, но реквизиты КПС и Организация остаются пустыми. Выделим основные причины, почему это происходит:

  1. Неверное понимание приоритетов загрузки в КД: В Конвертации данных правила и объекты обрабатываются в порядке приоритета. **Чем больше число приоритета, тем раньше загружается объект.** Если у справочника Организации приоритет 1900, а у переносимого справочника 4100, то справочник с приоритетом 4100 будет обрабатываться **раньше**, чем создадутся и запишутся организации. В момент выполнения метода НайтиПоКоду("000000001") нужной организации в базе-приемнике еще физически нет.
  2. Подчиненность справочников: Если справочник является подчиненным (например, классификатор или реквизит связан с владельцем), метод НайтиПоКоду(Код, ПоискПоПолномуКоду, Владелец) требует передачи третьего параметра — ссылки на владельца. Без указания владельца метод возвращает пустую ссылку.
  3. Прямое создание элементов в обработчиках обходит кэш КД: Вызов метода СоздатьЭлемент() вручную прямо в обработчике обходит внутренние механизмы поиска и сопоставления ссылок (GUID) Конвертации данных. Это приводит к дублированию объектов и некорректным связям.

Вариант решения 1. Корректировка приоритетов загрузки

Проанализируем порядок выгрузки и загрузки объектов. Для того чтобы организация или классификаторы находились по коду во время выполнения кода загрузки другого объекта, они должны быть записаны в базу-приемник **до** начала обработки этого объекта.

Для исправления порядка загрузки выполним следующие действия:

  1. Увеличим приоритет загрузки для справочников-справочников НСИ (например, Организации, КПС, КОСГУ), установив им более высокое числовое значение, чем у зависимых справочников.
  2. Если объекты не прописаны в Правилах Выгрузки Данных (ПВД), убедимся, что они выгружаются по ссылкам перед основной выгрузкой данных.

Вариант решения 2. Правильная архитектура КД через входящие и исходящие данные

Вместо ручного создания объекта через Справочники.СтатьиАналитикиОплатыЧекаККМ.СоздатьЭлемент() в коде, рекомендуется использовать штатные механизмы платформы "Конвертация данных". Это позволит корректно сопоставлять ссылки и передавать данные без прямых вызовов методов записи.

Рассмотрим по шагам, как настроить правила перегрузки реквизита, которого нет в источнике:

  1. Создадим отдельное ПКО без источника: "Пусто" -> "СтатьиАналитикиОплатыЧекаККМ".
  2. В основном ПКО (где переносится наш объект) для реквизита ОсновнаяСтатьяАналитикиОплаты добавим ПКС с пустым источником. В качестве правила конвертации укажем ранее созданное правило "Пусто" -> "СтатьиАналитикиОплатыЧекаККМ".
  3. В обработчике Перед выгрузкой этого ПКС сформируем структуру исходящих данных:
    
    ИсходящиеДанные = Новый Структура;
    ИсходящиеДанные.Вставить("КПС", "09050000000000130");
    ИсходящиеДанные.Вставить("КФО", Перечисления.КВД.Внебюджет);
    ИсходящиеДанные.Вставить("КЭК", "130");
    ИсходящиеДанные.Вставить("Наименование", "Внебюджет");
    ИсходящиеДанные.Вставить("Организация", "000000001");
    
  4. В правиле "Пусто" -> "СтатьиАналитикиОплатыЧекаККМ" добавим ПКС для всех реквизитов (КПС, КФО, КЭК, Наименование, Организация) и для каждого из них установим флаг "Получить из входящих данных".

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

Вариант решения 3. Заполнение реквизитов в обработчике После загрузки

Если требуется привязать один и тот же созданный элемент ко всем загружаемым объектам, поиск или заполнение реквизита безопаснее выполнять в обработчике После загрузки объекта-приемника. В этот момент основной объект уже создан в памяти как Объект, а связанные справочники НСИ уже загружены в базу.

Пример кода в обработчике После загрузки:


СсылкаОрг = Справочники.Организации.НайтиПоКоду("000000001");
СсылкаКПС = Справочники.КлассификационныеПризнакиСчетов.НайтиПоКоду("09050000000000130");

Если ЗначениеЗаполнено(СсылкаОрг) И ЗначениеЗаполнено(СсылкаКПС) Тогда
    НайденнаяСтатья = Справочники.СтатьиАналитикиОплатыЧекаККМ.НайтиПоРеквизиту("Наименование", "Внебюджет");
    
    Если Не ЗначениеЗаполнено(НайденнаяСтатья) Тогда
        НоваяСтатья = Справочники.СтатьиАналитикиОплатыЧекаККМ.СоздатьЭлемент();
        НоваяСтатья.Наименование = "Внебюджет";
        НоваяСтатья.Организация = СсылкаОрг;
        НоваяСтатья.КПС = СсылкаКПС;
        НоваяСтатья.Записать();
        НайденнаяСтатья = НоваяСтатья.Ссылка;
    КонецЕсли;
    
    Объект.ОсновнаяСтатьяАналитикиОплаты = НайденнаяСтатья;
КонецЕсли;

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

← На главную