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