Как исключить битые ссылки Объект не найден при выгрузке в Конвертации данных 2.0

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

При работе с обменами данными в среде 1С:Предприятие одной из самых частых и неприятных проблем является наличие «битых» ссылок. В интерфейсе пользователя они отображаются как <Объект не найден>, за которым следует уникальный идентификатор (GUID). Такие ссылки возникают, когда в базе данных существует запись, ссылающаяся на объект, который был физически удален без контроля ссылочной целостности.

В этой статье мы подробно разберем, как правильно обрабатывать такие ситуации в инструменте Конвертация данных 2.0 (КД 2), чтобы избежать выгрузки некорректных данных в приемник. Мы рассмотрим несколько подходов: от использования стандартных библиотек до низкоуровневых проверок платформы.

Почему проверка через строковое представление — это плохой путь

Разберем типичную ошибку начинающих разработчиков. Часто пытаются использовать проверку через поиск подстроки в наименовании или строковом представлении объекта. Рассмотрим этот пример кода:


Если Найти(Источник.Наименование, "Объект не найден") <> 0 Тогда
    Отказ = Истина;
КонецЕсли;

Проанализируем ситуацию: такой подход крайне ненадежен по нескольким причинам. Во-первых, обращение к свойству Наименование у «битой» ссылки может привести к ошибке исполнения, так как объекта физически не существует. Во-вторых, строковое представление "Объект не найден" зависит от локализации платформы (на английском это будет "Object not found"). В-третьих, это избыточная операция преобразования в строку, которая замедляет выгрузку при больших объемах данных.

Способ 1. Использование функций БСП (самый оптимальный)

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

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


// Проверяем, существует ли физически объект в базе данных
Если НЕ ОбщегоНазначения.СсылкаСуществует(Источник) Тогда
    Отказ = Истина;
КонецЕсли;

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

Способ 2. Проверка без использования БСП (средствами платформы)

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

В том же обработчике Перед выгрузкой можно написать:


Если Источник.ПолучитьОбъект() = Неопределено Тогда
    Отказ = Истина;
КонецЕсли;

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

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

Способ 3. Выбор места обработки: ПКО или ПКС

Рассмотрим подробнее архитектурный вопрос: где именно писать проверку? Это зависит от вашей задачи.

  1. ПКО (Правило конвертации объекта): Если нам нужно полностью пропустить объект (например, документ), если он содержит «битую» ссылку на самого себя или критически важный реквизит. Установка Отказ = Истина в ПКО прерывает выгрузку всего объекта.
  2. ПКС (Правило конвертации свойства): Если нам нужно выгрузить документ, но очистить в нем только конкретное поле, которое ссылается на «несуществующий» справочник. В этом случае код пишется в ПКС в обработчике Перед выгрузкой.

Посмотрим на пример кода для ПКС:


// Проверяем значение конкретного реквизита
Если НЕ ОбщегоНазначения.СсылкаСуществует(Значение) Тогда
    // Вариант А: Просто не выгружать это свойство (в приемнике останется пустым)
    Отказ = Истина; 
    
    // Вариант Б: Принудительно установить пустую ссылку нужного типа
    // Значение = Справочники.Контрагенты.ПустаяСсылка();
КонецЕсли;

Нюансы с XML и пустыми узлами

Проанализируем ситуацию с формированием результирующего файла. Если в ПКС вы установите Отказ = Истина, то тег этого свойства в XML-файле просто не будет создан. Если база-приемник имеет жесткую структуру или специфические обработчики «После загрузки», отсутствие тега может быть интерпретировано неоднозначно.

Если вам необходимо, чтобы в приемник пришла именно «Пустая ссылка», лучше не использовать Отказ = Истина, а явно присваивать Значение = Неопределено или вызывать метод ПустаяСсылка() для соответствующего типа метаданных. В этом случае в XML будет записан пустой идентификатор (00000000-00-00-00-00-000000000000), который платформа 1С корректно распознает как пустую ссылку.

Глобальные способы решения проблемы

Если проблема «битых» ссылок в вашей базе носит массовый характер, прописывание кода в каждом правиле — это трудоемкий процесс. Рассмотрим, как автоматизировать эту задачу.

Использование глобальных обработчиков: В КД 2 можно определить алгоритм или использовать глобальный обработчик Перед выгрузкой объекта. Там можно перебрать все реквизиты объекта через метаданные и проверить их на валидность. Это позволит один раз написать универсальный код для всей конвертации.

Профилактика данных: Прежде чем настраивать сложные фильтры в конвертации, крайне рекомендуется выполнить «Тестирование и исправление» (ТиИ) информационной базы. В настройках ТиИ выберите пункты:

После очистки базы на уровне СУБД проблема «Объект не найден» исчезнет сама собой, и правила конвертации будут работать быстрее и чище, не требуя дополнительных проверок в коде.

Резюме

Для эффективной борьбы с «битыми» ссылками в Конвертации данных 2.0 используйте функцию ОбщегоНазначения.СсылкаСуществует() в обработчиках ПКО или ПКС. Избегайте проверок через Строка() или Наименование, так как это ведет к ошибкам и снижению производительности. Всегда старайтесь сначала исправить данные в исходной базе методами тестирования и исправления, прежде чем программно обрабатывать их при обмене.

← На главную