Столкновение с неприятной фразой «Объект не найден» рано или поздно становится неизбежным как для каждого пользователя, так и разработчика в 1С. Как поступить в такой ситуации? Главное, отличить друг от друга пустую ссылку, Неопределено, NULL. Они в запросе «битая ссылка» ведут себя по-разному.
Подскажем один интересный и полезный прием. Он реально поможет осознать, битая ссылка в запросе 1с возникла перед пользователем или это иной вариант. Например, допустим, из-за некорректной настройки прав доступа невозможно увидеть представление объекта информационной базы, которое запрещено для открытия и просмотра. В таком случае тоже появляется надпись на экране «Объект не найден». Но это уже совсем другая история.
- Почему и для чего нужна 1с проверка на битую ссылку
- Проверка на битую ссылку в запросе через реквизит на NULL
- Обозначим разницу в понятиях: NULL, пустая ссылка и Неопределено
- Как проверить на битую ссылку 1с документ ЭлектронноеПисьмо с реквизитом составного типа
- Проверка на битую ссылку в запросе 1с через фильтр «пустая ссылка»
- Как оформить проверку в запросе битая ссылка в служебной обработке
- Пример составного запроса с временной таблицей
- Как проверить на битую ссылку 1с другими способами
- Типичные ошибки в запросе битая ссылка при проверке на NULL
- Полезные советы для отладки запросов с проверкой на NULL
- Пример с логическим флагом в выборке
- Готовые обработки, шаблоны проверки на битую ссылку в запросе 1с
- Заключение
Почему и для чего нужна 1с проверка на битую ссылку
Начнем с азов ― разберемся, кто и в чем виноват. Затем, традиционно, ответим на извечный русский вопрос, «что делать».
Имеющий дело с информационной базой 1С: Предприятие должен понимать, что перед ним сложно выстроенная структурно взаимосвязь объектов: справочники, документы, регистры. Чтобы система функционировала без сбоев, выдавала достоверные учетные записи, между объектами должны корректно выстраиваться связи.
Так как обозначенная взаимосвязь реализуется через ссылки, следует вылавливать и избавляться от непрошеных гостей ― «битых ссылок». Проще говоря, ловушек, отправляющих пользователя к объектам, которых уже нет в базе данных.
Даже если поначалу кажется, что лично вам «битые ссылки» не встретятся, поверьте опытным экспертам на слово ― это заблуждение. Разработчику рекомендуется сразу закладывать в конфигурации проверки качества данных. Такая предусмотрительность поможет избежать ночных запусков обработки поиска битых ссылок.
Бухгалтера, экономисты, кадровики смогут спокойно работать с открывающимися в нужный момент документами. Цифры в отчетах всегда будут сходиться, если вовремя уделить внимание маленькой технической детальке ― битой ссылке. По крайней мере, программиста в расхождениях заполненных таблиц никто не сможет обвинить.
Следует запомнить также, что в некоторых обстоятельствах найденные битые ссылки трогать не рекомендуется. Речь идет о тех, которые относятся к закрытым периодам, архивным данным или особенностям старых релизов конфигурации. Решать вопрос об удалении надо коллегиально, после обсуждения с пользователями, работающими на платформе. Возможно, находки потребуется заменить или просто пометить как технический мусор. Автоматический подход к исправлению без понимания производственных задач может навредить.
Проверка на битую ссылку в запросе через реквизит на NULL
Вернемся на секунду к терминологии. Под битой ссылкой в 1С обычно понимается значение ссылочного типа, которое указывает на уже несуществующий объект в базе. В интерфейсе такая ссылка часто отображается как «Объект не найден (GUID)». При этом в коде метод Пустая() для нее возвращает Ложь, потому что тип и значение формально есть. В таблицах базы при обращении к реквизитам такого объекта запрос получает NULL. Недоразумение объясняется просто: хотя строк и в реестре или справочнике уже нет, значение ссылки еще где-то хранится.
Обозначим разницу в понятиях: NULL, пустая ссылка и Неопределено
Важно развести три разных состояния: NULL, пустая ссылка и Неопределено, иначе фильтры в запросах будут вести себя странно. NULL — это отсутствие значения в поле таблицы, чаще всего результат левого соединения или попытки обратиться к реквизиту несуществующего объекта. Пустая ссылка — это типизированное значение вида СправочникСсылка.Контрагенты, которое указывает «в никуда», но объект при этом считается существующим значением, а Неопределено — это уже значение языка 1С, которое появляется, когда переменной вообще ничего не присвоено.
В 1с найти битые ссылки запросом можно с помощью разных формулировок. Объединяет их все общая концепция: поиск битых ссылок с использованием запроса основывается на следующих допусках:
- во-первых, ссылка не пустая;
- во-вторых, не равняется Неопределено, то есть, переменной ничего не присвоено;
- в-третьих, обращение к реквизиту объекта выдает NULL (отсутствие значения в поле таблицы). При этом доподлинно известно, что реквизит в живом объекте обязательно был заполнен (например, дата, номер, имя владельца и т.д.).
Тогда условие в запросе будет состоять из двух частей: исключаем пустые / Неопределено значения ссылки и проверяем обязательный реквизит на ЕСТЬ NULL.
Напомним о важном условии, которое необходимо соблюдать. В запросах 1С нельзя просто написать "Поле = NULL" или "Поле <> NULL" — движок языка так не понимает. Для проверки на NULL используется специальный оператор "ЕСТЬ NULL", который возвращает Истина, если значение действительно равно NULL, и Ложь во всех остальных случаях. А для подстановки другого значения вместо NULL служит функция ЕСТЬNULL(Поле, ЗначениеПоУмолчанию), но это уже про обработку, а не про фильтрацию.
Как проверить на битую ссылку 1с документ ЭлектронноеПисьмо с реквизитом составного типа
Приведем конкретные примеры для ответа на частые вопросы клиентов, имеющих дело с разными конфигурациями.
- Документ ЭлектронноеПисьмоВходящее имеет реквизит ВзаимодействиеОснование составного типа, который может ссылаться на разные документы с реквизитом Дата. Логично предположить, что, как у любого «живого» документа, здесь реквизит Дата всегда заполнен. Поэтому, если при обращении к ВзаимодействиеОснование.Дата запрос видит NULL, значит, объект основание либо удален, либо поврежден, а ссылка фактически битая.
- Сформулируем типичный запрос для проверки битых оснований:
ВЫБРАТЬ ЭлектронноеПисьмоВходящее.Ссылка КАК Ссылка, ЭлектронноеПисьмоВходящее.ВзаимодействиеОснование КАК ВзаимодействиеОснование ИЗ Документ.ЭлектронноеПисьмоВходящее КАК ЭлектронноеПисьмоВходящее ГДЕ ЭлектронноеПисьмоВходящее.ВзаимодействиеОснование.Дата ЕСТЬ NULL И ЭлектронноеПисьмоВходящее.ВзаимодействиеОснование <> Неопределено ```
Здесь как раз и зашита наша логика: если Дата у основания NULL, а сама ссылка не равна Неопределено, то это кандидат на битую ссылку. В реальной задаче сюда часто добавляют еще и проверку на пустую ссылку, если тип реквизита не составной и заранее известен.
Проверка на битую ссылку в запросе 1с через фильтр «пустая ссылка»
Если известно, что ВзаимодействиеОснование может указывать, скажем, только на один вид документа, то можно добавить фильтр и по пустой ссылке этого типа.
ГДЕ ЭлектронноеПисьмоВходящее.ВзаимодействиеОснование.Дата ЕСТЬ NULL И ЭлектронноеПисьмоВходящее.ВзаимодействиеОснование <> Неопределено И ЭлектронноеПисьмоВходящее.ВзаимодействиеОснование <> ЗНАЧЕНИЕ(Документ.ЗаказКлиента.ПустаяСсылка) ```
Такое условие сначала отбрасывает явные пустые ссылки, а затем оставляет только те значения, где при обращении к реквизиту Дата возникает NULL — то есть потенциально битые ссылки. На практике это уменьшает количество ложных срабатываний и делает выборку аккуратнее.
Когда реквизит составного типа (например, ДокументСсылка.РеализацияТоваровУслуг или ДокументСсылка.ЗаказКлиента), напрямую сослаться на ПустаяСсылка для всех вариантов сразу нельзя. Поэтому проще опираться на общий для всех вариантов, гарантированно заполненный реквизит: Дата, Номер, Представление, Ссылка и так далее. В этом и прелесть подхода: не нужно знать все варианты типов наперед, достаточно выбрать один надежный реквизит, который в живых объектах пустым не бывает.
Разберем два наиболее важных реквизита. Первый ― универсальный для всех документов в типовых конфигурациях реквизит Дата. Конечно, если он не отключался специально.
Пример:
ГДЕ Сделка.ВзаимодействиеОснование.Дата ЕСТЬ NULL И Сделка.ВзаимодействиеОснование <> Неопределено ```
Такой запрос надежно выловит все записи, у которых основание либо отсутствует в базе, либо повреждено. В доработанных конфигурациях полезно дополнительно проверить настройки метаданных, чтобы не полагаться на предположения вслепую.
Иногда удобнее проверять не дату, а Представление ссылки: если объект не найден, его текстовое представление в запросе может оказаться NULL.
ГДЕ Регистратор.Ссылка.Представление ЕСТЬ NULL И Регистратор.Ссылка <> Неопределено ```
Такой прием встречается, например, в обработках поиска битых ссылок по регистраторам регистров, где достаточно понимать, что регистратор «мертвый», без подробностей по его реквизитам. Главное — не забыть при этом отсеять пустые ссылки конкретного типа, если они по бизнес-логике допустимы.
В определенных ситуациях полезнее идти не прямым путем проверки самой ссылки на ЕСТЬNULL в запросе. Следует отметить, что прямая проверка обычно приветствуется при левых соединениях.
При поиске битых ссылок в существующих записях лучше действовать через реквизит. Метод одинаково работает и для одиночного ссылочного реквизита, и для составного типа, и для ситуаций, когда объект давно удален, а ссылка на него еще хранится где-нибудь в регистре. То есть разработчик получает единый, очень практичный паттерн, который легко переиспользовать в разных запросах.
Краткая, но важная пометка: не забывайте о производительности. Любое обращение к реквизитам ссылочного поля в запросе — это дополнительная работа для СУБД и платформы, особенно на больших таблицах. Поэтому не стоит лепить проверки через точку в каждом SELECT без надобности. Практичнее сначала отладить, оценить объем данных, а уже потом выпускать в боевую регламентную обработку. При больших массивах иногда полезнее вначале отобрать подозрительные ссылки в промежуточный набор, а уже потом проверять их по реквизитам отдельным запросом.
Как оформить проверку в запросе битая ссылка в служебной обработке
На практике поиск битых ссылок обычно выносят в отдельную обработку, которая по расписанию или вручную прогоняет набор стандартных запросов. Один из запросов может как раз содержать проверку вида «Ссылка.Реквизит ЕСТЬNULL И Ссылка <> Неопределено». В дальнейшем результат сохраняется во временную таблицу или сразу выводится пользователю. Такой подход позволяет не только находить проблемы, но и накапливать статистику по конфигурации: где чаще всего «сыпятся» ссылки, какие документы удаляются, какие регистры стоит пересмотреть.
Пример составного запроса с временной таблицей
Приведенный выше пример проверки на битую ссылку 1с в документе ЭлектронноеПисьмо с реквизитом составного типа чуть усложним. А именно: добавим временную таблицу для дальнейшего анализа:
ВЫБРАТЬ ЭлектронноеПисьмоВходящее.Ссылка КАК Письмо, ЭлектронноеПисьмоВходящее.ВзаимодействиеОснование КАК Основание ПОМЕСТИТЬ ВтБитыеОснования ИЗ Документ.ЭлектронноеПисьмоВходящее КАК ЭлектронноеПисьмоВходящее ГДЕ ЭлектронноеПисьмоВходящее.ВзаимодействиеОснование.Дата ЕСТЬ NULL И ЭлектронноеПисьмоВходящее.ВзаимодействиеОснование <> Неопределено; ВЫБРАТЬ ВтБитыеОснования.Письмо, ВтБитыеОснования.Основание ИЗ ВтБитыеОснования КАК ВтБитыеОснования ```
Во второй части запроса можно уже соединять временную таблицу с другими данными, строить отчеты, предлагать пользователю варианты исправления. Такой сценарий особенно удобно внедрять в регламентные проверки качества данных.
Как проверить на битую ссылку 1с другими способами
Помимо варианта «через реквизит в запросе» существуют и другие техники, которые полезно знать для полноты картины. Например, часто используется сравнение строкового представления ссылки с подстрокой "<Объект не найден>", либо попытка вызвать метод ПолучитьОбъект() и проверить, вернул ли он Неопределено. Эти способы больше подходят для процедурного кода и обработок, но в некоторых случаях их комбинируют с запросами, чтобы сначала отобрать кандидатов, а затем точно проверить каждую ссылку в цикле.
Во многих проектах встречается универсальная функция, которая по ссылке определяет, существует ли объект в базе, выполняя внутренний запрос к соответствующей таблице. В самом простом варианте она строит текст запроса вроде "ВЫБРАТЬ Ссылка ИЗ <Объект> ГДЕ Ссылка = &Ссылка" и проверяет, пустой ли результат. Такой подход хорошо сочетается с запросами, в которых сначала отбираются подозрительные ссылки по признаку NULL в реквизитах, а затем в коде для каждой ссылки вызывается универсальная проверка.
Типичные ошибки в запросе битая ссылка при проверке на NULL
Самая частая ошибка — пытаться сравнивать поля со значением NULL через обычные операторы «=» или «<>», как это делают с пустыми ссылками или строками. В языке запросов 1С так не работает. Разработчик удивляется, почему выборка пустая или, наоборот, слишком большая.
Вторая популярная ошибка — забывать про Неопределено и пустые ссылки. Другими словами, проверять только реквизит на ЕСТЬNULL, но не отбрасывать случаи, когда сама ссылка не заполнена по бизнес-логике.
Полезные советы для отладки запросов с проверкой на NULL
Когда перед разработчиком стоит задача найти в 1С 8.3 битые ссылки, рекомендуется взять на вооружение несколько полезных приемов. Они помогут отладить запрос с проверкой на NULL.
Во-первых, удобно временно выводить в выборку дополнительный флаг вроде «РеквизитПустой = Реквизит ЕСТЬ NULL». Тогда вы собственными глазами видите, для каких строк условие срабатывает.
Во-вторых, стоит проверить результат на небольшой тестовой базе, где заведомо созданы несколько битых ссылок. Таким образом можно убедиться, что они реально попадают в выборку.
Пример с логическим флагом в выборке
Добавим в предыдущий пример вычисляемое поле для наглядности:
ВЫБРАТЬ ЭлектронноеПисьмоВходящее.Ссылка КАК Ссылка, ЭлектронноеПисьмоВходящее.ВзаимодействиеОснование КАК ВзаимодействиеОснование, ЭлектронноеПисьмоВходящее.ВзаимодействиеОснование.Дата ЕСТЬ NULL КАК БитаяСсылка ИЗ Документ.ЭлектронноеПисьмоВходящее КАК ЭлектронноеПисьмоВходящее ГДЕ ЭлектронноеПисьмоВходящее.ВзаимодействиеОснование.Дата ЕСТЬ NULL И ЭлектронноеПисьмоВходящее.ВзаимодействиеОснование <> Неопределено ```
Поле БитаяСсылка будет содержать Истина для строк с NULL в дате основания, что удобно для визуальной проверки и последующей автоматической обработки. После отладки такое поле обычно убирают из боевой версии запроса, чтобы не засорять выборку лишними колонками.
Готовые обработки, шаблоны проверки на битую ссылку в запросе 1с
Избитая фраза «время ― деньги» никогда не была для людей дела пустым звуком. Поэтому любая команда должна настраиваться на повышение производительности в своей сфере.
Изучив сведения об основных отличиях NULL от пустой ссылки и Неопределено, стоит закрепить их в командных стандартах разработки. Где-то это будет правило написания запросов к регистрам, где-то — набор готовых шаблонов проверок, которые можно копировать в новые обработки. Тогда даже начинающий специалист быстрее начнет писать предсказуемые запросы и меньше ломать голову над странными результатами выборки.
Сэкономить большое количество рабочего времени и добиться стабильной работы системы 1С: Предприятие помогут готовые решения под ключ от компании MoscowSoft.
Опытной команде незачем тратить драгоценное время на написание проверок «с нуля». Занимаясь решением задач переноса данных и сопровождения программ на платформе «1С: Предприятие» с 2015 года, компания MoscowSoft создала десятки тиражных продуктов.
Готовые обработки, архив библиотек из собственных проектов помогает автоматизировать миграции, интеграции и очистку данных от мусорных и битых ссылок. Для официального партнера фирмы 1С и поставщика тиражных решений, каковым является MoscowSoft, проверки на битые и пустые ссылки ― ежедневная рутина.
Начинающий разработчик получит немало пользы от сотрудничества с такой командой. Ведь большая часть сложных задач ― от методики проверки до отладки запросов ― уже решена грамотными специалистами.
Заключение
Прием с проверкой «ссылка не пустая, но ее реквизит равен NULL» прост, хорошо формализуется в запросах и отлично работает как базовый инструмент поиска битых ссылок в 1С. Главное — осознанно выбирать проверяемый реквизит, не забывать про Неопределено и пустые ссылки. Не стесняться использовать готовые наработки, в том числе от таких команд, как MoscowSoft. Но вот вопрос: оставлять ли ответственность за чистоту данных только на разработчике, или пора учить и бизнес-пользователей понимать, что такое «битая ссылка» и чем она им грозит?














































