Как поставить условие в запросе на битые ссылки в 1С:Предприятии?

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

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

Рассмотрим типовую ситуацию, с которой столкнулся пользователь. Исходный запрос, направленный на поиск расхождений в реквизитах справочника «Пользователи», выглядел следующим образом:


ВЫБРАТЬ
	Пользователи.Ссылка КАК Пользователь,
	Пользователи.ФизЛицо КАК ФизЛицо,
	Пользователи.ФизическоеЛицо КАК ФизическоеЛицо,
	Пользователи.Подразделение КАК Подразделение,
	Пользователи.ПометкаУдаления КАК ПометкаУдаления
ИЗ
	Справочник.Пользователи КАК Пользователи
ГДЕ
	Пользователи.ФизЛицо <> Пользователи.ФизическоеЛицо
	И Пользователи.ПометкаУдаления = ЛОЖЬ
	И Пользователи.ФизическоеЛицо = ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)

В результате выполнения такого запроса в поле Пользователи.ФизЛицо возвращались значения вида «<Объект не найден>». Наша задача — научиться фильтровать эти строки непосредственно на уровне запроса, чтобы получать только корректные данные и исключать проблемные записи.

Причины возникновения «битых» ссылок

Прежде чем перейти к методам отсечения, давайте выясним, почему вообще появляются «битые» ссылки. Понимание корневых причин поможет нам не только исправлять, но и предотвращать подобные ситуации в будущем. «Битые» ссылки возникают, когда в реквизите объекта хранится ссылка на объект, который был некорректно удален из базы данных или чей внутренний идентификатор не может быть сопоставлен с существующим элементом. Разберем основные причины, которые приводят к нарушению ссылочной целостности:

  1. Недостаточно безопасные настройки прав. Если пользователи имеют возможность прямого удаления элементов базы данных без контроля их использования и проверки наличия ссылок на удаляемый объект, это может привести к нарушению ссылочной целостности.
  2. Случайное программное удаление данных. Иногда программный код может некорректно удалять объекты, не проверяя, есть ли на них ссылки из других объектов. Чтобы подготовить объекты к удалению, настоятельно рекомендуем использовать стандартную функцию УдалитьОбъекты, которая проверяет наличие ссылок на удаляемые объекты и предупреждает пользователя или отменяет удаление при их обнаружении.
  3. Неверно настроенный обмен данными. Ошибки при обмене данными между различными конфигурациями 1С могут привести к тому, что на одной стороне объект будет удален, а на другой останется ссылка на него, становящаяся «битой». Важно тщательно настраивать правила конвертации и сопоставления объектов.
  4. Аварийные завершения работы информационных баз. В редких случаях некорректное завершение работы системы, аппаратные сбои или ошибки файловой системы могут приводить к повреждению данных в базе и, как следствие, к появлению «битых» ссылок, когда идентификатор объекта существует, но сам объект физически отсутствует.

Последствия наличия «битых» ссылок

Наличие «битых» ссылок в информационной базе — это серьезная проблема, которая может привести к ряду негативных последствий, затрудняющих нормальную работу системы и искажающих данные:

  1. Ошибки при работе пользователей. Попытка открыть объект, содержащий «битую» ссылку, или документ, ссылающийся на такой объект, часто вызывает стандартные ошибки типа «Объект не найден». Это приводит к блокировке работы и необходимости вмешательства администратора или программиста.
  2. Некорректное проведение документов. Если документ ссылается на несуществующий объект (например, на несуществующий склад, контрагента или позицию номенклатуры), его проведение может быть невозможно или, что еще хуже, приводить к искажению данных в регистрах, если логика проведения не учитывает такие ситуации.
  3. Проблемы с отчетами. Отчеты, использующие данные с «битыми» ссылками, могут выдавать ошибки, формироваться некорректно, показывать неполную или недостоверную информацию, что мешает принятию управленческих решений.
  4. Затруднения при обновлении конфигурации. В некоторых случаях наличие «битых» ссылок может препятствовать корректному обновлению информационной базы, вызывая ошибки при конвертации данных или при попытке модификации структуры, затрагивающей проблемные объекты.

Методы отсечения «битых» ссылок в запросах 1С

Перейдем к главному вопросу: как же нам отфильтровать строки с «битыми» ссылками на уровне запроса? Мы рассмотрим несколько подходов, основанных на использовании оператора ЕСТЬ NULL. Этот оператор является ключевым для решения нашей задачи.

Использование реквизитов объекта для проверки на NULL

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

Один из самых распространенных и интуитивно понятных способов — это проверка на NULL таких атрибутов, как Наименование или Код ссылочного объекта. Давайте посмотрим на пример, предложенный в обсуждении, где используется проверка по наименованию:


ВЫБРАТЬ
	Пользователи.Ссылка КАК Пользователь,
	Пользователи.ФизЛицо КАК ФизЛицо,
	Пользователи.ФизическоеЛицо КАК ФизическоеЛицо,
	Пользователи.Подразделение КАК Подразделение,
	Пользователи.ПометкаУдаления КАК ПометкаУдаления
ИЗ
	Справочник.Пользователи КАК Пользователи
ГДЕ
	Пользователи.ФизЛицо <> Пользователи.ФизическоеЛицо
	И Пользователи.ПометкаУдаления = ЛОЖЬ
	И Пользователи.ФизическоеЛицо = ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)
	И НЕ Пользователи.ФизЛицо.Наименование ЕСТЬ NULL 

В этом примере условие И НЕ Пользователи.ФизЛицо.Наименование ЕСТЬ NULL гарантирует, что в выборку попадут только те строки, для которых реквизит ФизЛицо является корректной ссылкой, то есть у него можно получить Наименование. Если ФизЛицо — «битая» ссылка, то попытка обратиться к Пользователи.ФизЛицо.Наименование вернет NULL, и строка будет отсечена условием НЕ ЕСТЬ NULL.

Аналогично можно использовать проверку по Код, если этот реквизит есть у объекта, на который ссылается поле:


И НЕ Пользователи.ФизЛицо.Код ЕСТЬ NULL

Важно помнить, что если мы хотим отсечь битые ссылки, нам нужно использовать условие НЕ ... ЕСТЬ NULL, то есть, нас интересуют записи, где реквизит не является NULL. Это подтверждает, что объект существует и его атрибут доступен.

Прямая проверка на NULL для самой ссылки

Одним из наиболее прямых, универсальных и часто рекомендуемых способов является проверка на NULL непосредственно для самого реквизита Ссылка объекта, на который указывает "битая" ссылка. То есть, условие будет выглядеть как Объект.Реквизит.Ссылка ЕСТЬ NULL. Важно понимать, что "битая" ссылка не является пустой в смысле метода Пустая(); для нее метод Пустая() вернет Ложь. Однако, при попытке доступа к ее реквизиту Ссылка (например, Пользователи.ФизЛицо.Ссылка), платформа вернет NULL, поскольку сам объект, на который она указывает, не найден.

Поэтому, чтобы исключить «битые» ссылки, мы будем использовать условие И НЕ Пользователи.ФизЛицо.Ссылка ЕСТЬ NULL. Это наиболее чистый и эффективный способ, поскольку реквизит Ссылка есть у любого ссылочного объекта, в отличие от Код или Наименование, которые могут отсутствовать у некоторых типов объектов.


ВЫБРАТЬ
	Пользователи.Ссылка КАК Пользователь,
	Пользователи.ФизЛицо КАК ФизЛицо,
	Пользователи.ФизическоеЛицо КАК ФизическоеЛицо,
	Пользователи.Подразделение КАК Подразделение,
	Пользователи.ПометкаУдаления КАК ПометкаУдаления
ИЗ
	Справочник.Пользователи КАК Пользователи
ГДЕ
	Пользователи.ФизЛицо <> Пользователи.ФизическоеЛицо
	И Пользователи.ПометкаУдаления = ЛОЖЬ
	И Пользователи.ФизическоеЛицо = ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)
	И НЕ Пользователи.ФизЛицо.Ссылка ЕСТЬ NULL 

Мы рекомендуем использовать именно этот подход как наиболее универсальный и надежный для отсечения «битых» ссылок в запросах.

Составные условия для комплексной проверки

Мы также можем комбинировать проверки для достижения более специфичных результатов. Например, если нам нужно убедиться, что ссылка в принципе заполнена (то есть не является NULL как результат внешнего соединения или неинициализированного поля) и при этом не является «битой» ссылкой:


ГДЕ
    НЕ Справочник.Пользователи.ФизЛицо ЕСТЬ NULL 
    И НЕ Справочник.Пользователи.ФизЛицо.Ссылка ЕСТЬ NULL

Первое условие НЕ Справочник.Пользователи.ФизЛицо ЕСТЬ NULL отсечет строки, где сам реквизит ФизЛицо не заполнен (т.е. имеет значение NULL, что может быть результатом левого соединения, когда нет соответствующей записи в правой таблице, или если поле не было инициализировано). Второе условие НЕ Справочник.Пользователи.ФизЛицо.Ссылка ЕСТЬ NULL отсечет строки, где ФизЛицо является «битой» ссылкой. Таким образом, мы получаем максимально очищенную выборку.

Как работает оператор «ЕСТЬ NULL» для «битых» ссылок

Мы уже упомянули, что оператор ЕСТЬ NULL играет ключевую роль. Давайте разберем его работу подробнее, чтобы у нас было четкое понимание. Оператор ЕСТЬ NULL в языке запросов 1С используется для проверки, является ли значение выражения слева от него NULL. В контексте «битых» ссылок, когда платформа 1С пытается получить доступ к реквизиту объекта, на который указывает «битая» ссылка, она не может его найти, так как объект физически отсутствует.

В результате этого обращения к несуществующему объекту, все его реквизиты (такие как Ссылка, Наименование, Код, и другие) возвращают значение NULL. Именно поэтому мы можем использовать ЕСТЬ NULL для их обнаружения.

Важно понимать, что NULL – это отсутствующее значение, которое не равно нулевому значению, пустой строке, пробелу, пустой ссылке (ЗНАЧЕНИЕ(Справочник.МойСправочник.ПустаяСсылка)) или значению Неопределено. NULL является типообразующим значением, то есть существует тип NULL и единственное значение этого типа. Сравнение любого значения с NULL (например, Null = Null) всегда возвращает Ложь (или UNKNOWN в SQL, что в 1С аналогично Ложь). Для корректной проверки на NULL необходимо использовать именно оператор ЕСТЬ NULL, а не прямое сравнение (например, Объект.Реквизит = NULL - это не будет работать ожидаемым образом).

Профилактика и исправление «битых» ссылок

Найти и отсечь «битые» ссылки в запросах — это лишь часть решения. Гораздо важнее предотвратить их появление и, при необходимости, корректно исправить уже существующие. Рассмотрим основные методы, которые помогут поддерживать ссылочную целостность нашей информационной базы:

  1. Тестирование и исправление информационной базы. В конфигураторе 1С существует мощный функционал «Тестирование и исправление». Мы можем запустить его, выбрав опцию «Проверка ссылочной целостности». Эта проверка выявляет физическое отсутствие объекта, на который указывает ссылка. Она может быть выполнена как в режиме отчета, так и с исправлением. Исправление может включать очистку «битых» ссылок (установление значения «пустая ссылка» или NULL) или создание новых объектов на месте отсутствующих, если это целесообразно и настроено.
  2. Безопасное удаление объектов. Всегда рекомендуем использовать стандартные механизмы удаления, предоставляемые платформой 1С. Для интерактивного удаления это функция УдалитьОбъекты(), доступная в меню «Все функции». Для программного удаления мы должны предварительно проверять наличие ссылок на удаляемый объект (например, через специализированные обработки, методы объекта или поиск по метаданным). Эти механизмы либо запрещают удаление, либо предлагают варианты обработки ссылок, что помогает избежать появления «битых» ссылок.
  3. Правильная настройка прав доступа. Ограничивайте права пользователей на прямое удаление объектов. Лучше настроить удаление через механизм пометки на удаление с последующим интерактивным или регламентным удалением помеченных объектов администратором. Это позволяет централизованно контролировать процесс удаления и обеспечивать проверку ссылочной целостности.
  4. Корректная настройка обмена данными. При настройке обменов между базами данных тщательно проверяйте правила конвертации и сопоставления объектов, особенно в сценариях удаления или переноса данных. Ошибки здесь часто приводят к появлению «битых» ссылок, когда объекты удаляются в одной базе, а ссылки на них остаются в другой.
  5. Программные обработки для поиска и удаления. В сообществе 1С существуют или могут быть разработаны универсальные алгоритмы и обработки, которые позволяют находить «битые» ссылки по всем таблицам базы данных и выполнять их коррекцию (например, заменять на пустые ссылки, либо выводить список для ручной обработки).

Производительность при поиске «битых» ссылок

При поиске «битых» ссылок важно учитывать производительность наших решений. Следует отметить, что обход выборки программно с получением строкового представления ссылки и сравнением его с «<Объект не найден>» является крайне неэффективным способом. Это требует избыточных обращений к базе данных для каждой строки и медленной обработки на стороне 1С-клиента, особенно при большом объеме данных.

Запросы, использующие оператор ЕСТЬ NULL на реквизитах ссылочного типа, как правило, значительно более производительны. Это связано с тем, что все операции по проверке выполняются непосредственно на стороне СУБД (системы управления базами данных), которая оптимизирована для таких задач. Таким образом, мы получаем уже отфильтрованные данные, минимизируя нагрузку на клиентское приложение 1С. Поэтому всегда старайтесь использовать условия в запросе, а не постобработку данных на стороне приложения.

Заключение

Мы выяснили, что «битые» ссылки — это серьезная проблема в 1С:Предприятии, способная привести к множеству ошибок и некорректной работе системы. Однако мы научились эффективно отсекать их в запросах с помощью оператора ЕСТЬ NULL. Самым надежным и производительным способом является использование условия НЕ Объект.Реквизит.Ссылка ЕСТЬ NULL. Помимо этого, мы подробно рассмотрели причины возникновения таких ссылок и методы их профилактики и исправления, которые помогут поддерживать нашу информационную базу в здоровом состоянии и избегать проблем с данными, обеспечивая стабильную и корректную работу.

← На главную