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