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