При работе с запросами в системе «1С:Предприятие 8.3» программисты часто сталкиваются с необходимостью обработки уникальных идентификаторов (GUID). Типичная задача — определить, является ли УИД пустым (состоящим из одних нулей), непосредственно в тексте запроса — есть готовая диагностика регистров на наличие битых ссылок. Однако стандартные методы сравнения со строкой здесь не работают из-за строгой типизации данных в СУБД. В этой статье мы подробно разберем, почему возникают ошибки при проверке УИД, и рассмотрим наиболее эффективные способы решения этой задачи.
Разберем типичную ошибку, которую совершают многие разработчики. Попытка сравнить результат функции УНИКАЛЬНЫЙИДЕНТИФИКАТОР() со строковым литералом "00000000-0000-0000-0000-000000000000" приводит к ошибке несовместимости типов. Это происходит потому, что в языке запросов 1С тип УникальныйИдентификатор не является строкой, а представляет собой двоичные данные. Даже если мы попытаемся использовать ВЫРАЗИТЬ(... КАК СТРОКА), это не всегда помогает, так как преобразование сложных типов в запросе имеет свои ограничения.
Проанализируем ситуацию: для системы «пустой УИД» — это не строка из нулей, а специфическое значение соответствующего типа. Поскольку в языке запросов нет возможности напрямую написать литерал типа УникальныйИдентификатор, нам приходится использовать обходные пути.
Это самый популярный и лаконичный «внутренний» способ проверки в запросе без использования внешних параметров. Идея заключается в том, чтобы получить УИД от заведомо пустой ссылки нужного справочника или документа с помощью конструкции ЗНАЧЕНИЕ(). Рассмотрим этот метод на примере проверки файла картинки в справочнике номенклатуры.
Выполним следующие шаги в конструкторе запроса (удобно через консоль запросов и инструменты анализа метаданных):
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка,
ВЫБОР
КОГДА УНИКАЛЬНЫЙИДЕНТИФИКАТОР(Номенклатура.ФайлКартинки) =
УНИКАЛЬНЫЙИДЕНТИФИКАТОР(ЗНАЧЕНИЕ(Справочник.НоменклатураПрисоединенныеФайлы.ПустаяСсылка))
ТОГДА "УИД пустой"
ИНАЧЕ "УИД заполнен"
КОНЕЦ КАК СтатусУИД
ИЗ
Справочник.Номенклатура КАК Номенклатура
В данном примере мы сравниваем УИД текущей записи с УИДом, который возвращает пустая ссылка справочника НоменклатураПрисоединенныеФайлы. Система корректно сопоставляет два значения одного типа, и условие отрабатывает правильно.
Если вам нужно универсальное решение или вы работаете с полем, тип которого может меняться, лучше всего передать пустой УИД в качестве параметра. Это наиболее «чистый» способ с точки зрения архитектуры кода 1С.
Рассмотрим реализацию в коде на встроенном языке:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| УНИКАЛЬНЫЙИДЕНТИФИКАТОР(Номенклатура.ФайлКартинки) <> &ПустойУИД";
// Передаем пустой идентификатор как параметр
Запрос.УстановитьПараметр("ПустойУИД", Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000"));
Результат = Запрос.Выполнить();
Этот метод исключает ошибки типизации, так как мы передаем объект нужного типа (УникальныйИдентификатор) непосредственно в движок запросов.
Выясним причину, по которой иногда может помочь простая проверка на ЕСТЬ NULL. Если поле имеет составной тип данных или данные выбираются через ЛЕВОЕ СОЕДИНЕНИЕ, и при этом ссылка в источнике отсутствует (равна Неопределено или запись в присоединяемой таблице не найдена), то функция УНИКАЛЬНЫЙИДЕНТИФИКАТОР() вернет значение NULL.
Посмотрим на пример обработки таких ситуаций:
ВЫБРАТЬ
Номенклатура.Ссылка,
ЕСТЬNULL(ПРЕДСТАВЛЕНИЕ(УНИКАЛЬНЫЙИДЕНТИФИКАТОР(Номенклатура.ФайлКартинки)), "Нет идентификатора") КАК УИД_Текст
ИЗ
Справочник.Номенклатура КАК Номенклатура
Важно помнить: обычная пустая ссылка (не NULL, а именно EmptyRef) имеет вполне реальный (хоть и нулевой) идентификатор, поэтому ЕСТЬ NULL не поймает пустую ссылку в обычном заполненном поле. Этот метод подходит только для соединений или полей со значением Неопределено.
Разберем по шагам критически важный аспект — влияние на скорость работы системы. Использование функции УНИКАЛЬНЫЙИДЕНТИФИКАТОР() в секции ГДЕ или в условиях соединения — это крайне ресурсоемкая операция. Рассмотрим причины:
УНИКАЛЬНЫЙИДЕНТИФИКАТОР), СУБД перестает использовать индексы по этому полю. Это приводит к полному сканированию таблицы (Full Scan), что на больших объемах данных (сотни тысяч и миллионы записей) вызовет колоссальные задержки.Сравните два варианта. Плохой вариант (медленно):
ГДЕ УНИКАЛЬНЫЙИДЕНТИФИКАТОР(Номенклатура.ФайлКартинки) = &ПустойУИД
Хороший вариант (быстро):
ГДЕ Номенклатура.ФайлКартинки = ЗНАЧЕНИЕ(Справочник.НоменклатураПрисоединенныеФайлы.ПустаяСсылка)
Во втором случае система использует индекс по полю ФайлКартинки, и запрос выполнится мгновенно.
Работа с идентификаторами напрямую оправдана только в специфических случаях:
Проанализируем пример получения строкового представления для выгрузки:
ВЫБРАТЬ
ВЫРАЗИТЬ(ПРЕДСТАВЛЕНИЕ(УНИКАЛЬНЫЙИДЕНТИФИКАТОР(Номенклатура.Ссылка)) КАК СТРОКА(36)) КАК GUID_Строкой
ИЗ
Справочник.Номенклатура КАК Номенклатура
Здесь мы используем ПРЕДСТАВЛЕНИЕ, чтобы получить визуальный текст УИДа, и ВЫРАЗИТЬ, чтобы привести его к стандартному строковому типу длиной 36 символов.
Мы рассмотрели несколько способов проверки пустого уникального идентификатора в запросе 1С. Подведем итог: если вам нужно просто проверить «пустоту» поля — проверяйте саму ссылку. Если же логика задачи требует работы именно с типом УникальныйИдентификатор, используйте сравнение с УИДом от ЗНАЧЕНИЕ(...ПустаяСсылка) или передавайте пустой идентификатор через параметры запроса. Это обеспечит стабильность работы кода и отсутствие ошибок типизации.