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