К статье
Практический материал

Разработка и Конфигурация · 11 мин

Запрос 1С: как проверить, что ссылка — это документ

Как в запросе 1С проверить, что ссылка относится к документу: ССЫЛКА, ТИП, ТИПЗНАЧЕНИЯ, ВЫРАЗИТЬ. Примеры кода, ошибки и способы отбора по типу документа.

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

Для этого в языке запросов 1С есть четыре рабочих инструмента: оператор ССЫЛКА в условиях, функции ТИПЗНАЧЕНИЯ() и ТИП(), а также оператор приведения ВЫРАЗИТЬ. У каждого своё назначение: одни проверяют тип, другие «сужают» составное поле до конкретного документа и открывают доступ к его реквизитам.

Ниже разобраны все варианты с примерами кода, типичными ошибками и рекомендациями по производительности. Примеры применимы к управляемым и обычным формам любых типовых и самописных конфигураций на платформе 1С:Предприятие 8.

Когда возникает задача проверки типа ссылки

Составные типы встречаются в типовых конфигурациях повсеместно: документ-основание, владелец справочника, поля регистров сведений, субконто в бухгалтерских планах счетов. Запрос, который обращается к такому полю без учёта типа, либо возвращает лишние строки, либо падает с ошибкой при обращении к реквизиту через точку.

Типичные сценарии, где нужно проверить, что ссылка — это документ конкретного вида:

  • отбор движений или связанных объектов только по определённому виду документа-основания;
  • объединение данных из разных документов в одном отчёте с разной логикой для каждого вида;
  • безопасное получение реквизита, который существует только у одного вида документа;
  • проверка значения субконто, где допустимы и справочники, и документы.

Важно понимать разницу: проверка типа нужна для отбора строк, а приведение типа — для доступа к данным. Часто требуется и то, и другое одновременно.

Оператор ССЫЛКА — основной способ отбора по виду документа

Самый простой и быстрый способ проверить, что ссылка указывает на документ нужного вида, — оператор ССЫЛКА в секции ГДЕ. Он сравнивает вид ссылки без обращения к данным самого документа, поэтому работает максимально быстро.

ВЫБРАТЬ

Движения.Регистратор,

Движения.Сумма

ИЗ

РегистрНакопления.Продажи КАК Движения

ГДЕ

Движения.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг

Такой запрос вернёт только те записи регистра, где регистратором является документ «Реализация товаров услуг». Если поле составное и содержит ссылки на другие виды документов, они будут отброшены на уровне СУБД без лишних соединений.

Оператор ССЫЛКА можно комбинировать с логическими операторами и использовать для нескольких видов через ИЛИ:

ГДЕ

(Основание ССЫЛКА Документ.ПоступлениеТоваровУслуг

ИЛИ Основание ССЫЛКА Документ.ВозвратТоваровОтПокупателя)

ТИПЗНАЧЕНИЯ и ТИП — универсальная проверка типа

Функция ТИПЗНАЧЕНИЯ() возвращает тип значения поля, а ТИП() — конкретный тип по имени объекта метаданных. Их сравнение даёт тот же результат, что и оператор ССЫЛКА, но синтаксис более универсален и иногда удобнее в динамически формируемых запросах.

ВЫБРАТЬ

Связанные.Объект

ИЗ

РегистрСведений.СвязанныеОбъекты КАК Связанные

ГДЕ

ТИПЗНАЧЕНИЯ(Связанные.Объект) = ТИП(Документ.ЗаказПокупателя)

Есть и обратная задача: проверить, что ссылка является документом вообще, любого вида. Прямой функции «это документ» в языке запросов нет, поэтому перечисляют нужные виды через ИЛИ либо используют ТИПЗНАЧЕНИЯ в сочетании со списком допустимых типов. На практике проще заранее ограничить состав поля в конфигураторе — тогда проверка в запросе вообще не потребуется.

По производительности вариант с ТИПЗНАЧЕНИЯ обычно сопоставим с ССЫЛКА, но оператор ССЫЛКА читается проще и однозначнее передаёт намерение. Для отбора по виду документа предпочтительнее именно он.

ВЫРАЗИТЬ — приведение составного поля к документу

Оператор ВЫРАЗИТЬ «сужает» составное поле до одного типа. После приведения к виду документа становится доступным обращение к его реквизитам через точку, а для строк, где ссылка другого вида, результат будет NULL.

ВЫБРАТЬ

ВЫРАЗИТЬ(Связанные.Объект КАК Документ.ЗаказПокупателя).Номер КАК НомерЗаказа,

ВЫРАЗИТЬ(Связанные.Объект КАК Документ.ЗаказПокупателя).Склад КАК Склад

ИЗ

РегистрСведений.СвязанныеОбъекты КАК Связанные

ГДЕ

Связанные.Объект ССЫЛКА Документ.ЗаказПокупателя

Здесь условие ССЫЛКА отсекает чужие виды документов, а ВЫРАЗИТЬ позволяет вытащить реквизиты «Номер» и «Склад». Без условия в ГДЕ запрос тоже выполнится, но в полях появятся пустые значения для строк с другими типами — это нужно учитывать при дальнейшей обработке результата.

Ещё одно применение ВЫРАЗИТЬ — соединение таблиц по составному полю. Приведение типа до соединения позволяет СУБД построить корректный план и избежать соединения со всеми таблицами составного типа, что критично для производительности на больших базах.

Сравнение способов проверки типа ссылки

СпособНазначениеДоступ к реквизитамКогда применять
ССЫЛКА Документ.ВидОтбор по виду ссылкиНетПростой отбор в ГДЕ, максимальная скорость
ТИПЗНАЧЕНИЯ() = ТИП()Отбор по виду ссылкиНетДинамически формируемые запросы, сложные условия
ВЫРАЗИТЬ(Поле КАК Документ.Вид)Приведение типаДаНужны реквизиты документа или соединение по составному полю

На практике способы комбинируют: ССЫЛКА в условии отбора плюс ВЫРАЗИТЬ в списке полей. Использовать ТИПЗНАЧЕНИЯ вместо ССЫЛКА «для единообразия» не стоит — читаемость запроса важнее, особенно когда его потом будет дорабатывать другой разработчик.

Сравнение вариантов

ССЫЛКА

Подходит для отбора строк по виду документа. Ограничение: не даёт доступа к реквизитам объекта.

ВЫРАЗИТЬ

Подходит для чтения реквизитов и соединений. Ограничение: без отбора в ГДЕ вернёт NULL для строк с другими типами.

ТИПЗНАЧЕНИЯ + ТИП

Подходит для универсальных проверок и построения запросов кодом. Ограничение: более громоздкий синтаксис.

Типичные ошибки при работе со ссылками на документы

Типичные ошибки
01
Обращение к реквизиту составного поля через точку без ВЫРАЗИТЬ — запрос падает с ошибкой «Поле не найдено» или возвращает непредсказуемый результат.
02
Соединение таблиц по составному полю без приведения типа — СУБД неявно соединяется со всеми таблицами составного типа, запрос резко замедляется.
03
Сравнение ссылки со строковым представлением или GUID в виде строки — типы не совпадают, условие всегда ложно.
04
Проверка ТИПЗНАЧЕНИЯ без учёта NULL — для пустых значений составного поля тип не определён, строка выпадает из выборки.
05
Отбор по виду документа в секции ИМЕЮЩИЕ вместо ГДЕ — условие применяется позже и медленнее, чем могло бы.

Отдельно стоит упомянуть пустые ссылки. Если поле может быть не заполнено, проверка «ССЫЛКА Документ.Вид» вернёт для него ложь, и строка не попадёт в результат. Когда нужно включить и пустые значения, добавляйте условие «ИЛИ Поле ЕСТЬ NULL» либо «ИЛИ Поле = ЗНАЧЕНИЕ(Документ.Вид.ПустаяСсылка)» в зависимости от структуры данных.

Ещё одна частая проблема — попытка проверить тип уже после того, как поле получено через точку из другого поля. Например, «Регистратор.ДокументОснование ССЫЛКА ...» может не сработать так, как ожидается, если «Регистратор» сам составного типа. Сначала приведите внешнее поле, потом работайте с вложенным.

Проверка результата и отладка запроса

После написания запроса проверьте его на реальных данных, где составное поле содержит разные виды ссылок. Удобный приём — временно вывести ТИПЗНАЧЕНИЯ(Поле) в список полей и посмотреть, какие типы реально встречаются в выборке.

Порядок действий
  1. 1
    Откройте консоль запросов и выполните запрос без условия на тип, выведя ТИПЗНАЧЕНИЯ(Поле) отдельной колонкой.
  2. 2
    Убедитесь, какие виды документов реально хранятся в поле.
  3. 3
    Добавьте условие «Поле ССЫЛКА Документ.НужныйВид» и проверьте, что лишние строки исчезли.
  4. 4
    Если нужны реквизиты документа, добавьте ВЫРАЗИТЬ и убедитесь, что значения реквизитов заполнены для нужных строк.
  5. 5
    Проверьте время выполнения на рабочем объёме данных и при необходимости добавьте индексируемые условия.
Контрольные точки

Как проверить результат

Состав выборки
Норма

В результате только ссылки нужного вида документа

Тревожный признак

Присутствуют другие виды или неожиданно пропали строки с пустыми значениями

Реквизиты через ВЫРАЗИТЬ
Норма

Поля заполнены для строк нужного вида

Тревожный признак

Все значения NULL — вероятно, вид документа указан неверно

Скорость выполнения
Норма

Запрос выполняется за приемлемое время на рабочей базе

Тревожный признак

Резкое замедление — проверьте соединения по неприведённым составным полям

FAQ

Чем отличается ССЫЛКА от ТИПЗНАЧЕНИЯ в запросе?

Оба проверяют вид ссылки, но ССЫЛКА — специализированный оператор с более простым синтаксисом: «Поле ССЫЛКА Документ.Вид». ТИПЗНАЧЕНИЯ — функция, возвращающая тип значения, которую можно сравнивать с ТИП() или использовать в выражениях. Для обычного отбора предпочтительнее ССЫЛКА.

Как проверить, что ссылка — документ любого вида, а не справочник?

Отдельной функции «это документ» нет. Перечислите допустимые виды через ИЛИ с оператором ССЫЛКА либо ограничьте состав типа поля в конфигураторе, чтобы туда вообще не попадали справочники.

Почему запрос с ВЫРАЗИТЬ возвращает NULL в реквизитах?

ВЫРАЗИТЬ приводит поле к указанному типу, и для строк, где ссылка имеет другой вид, результат приведения — NULL. Проверьте, совпадает ли вид документа в ВЫРАЗИТЬ с фактическими данными, и добавьте условие ССЫЛКА в ГДЕ, чтобы отобрать только нужные строки.

Можно ли использовать ССЫЛКА в параметрах виртуальных таблиц?

Нет, оператор ССЫЛКА применяется только в условиях ГДЕ и соединениях. В параметрах виртуальных таблиц отбор по виду документа задаётся через переданный массив ссылок или через условие в основном запросе после обращения к виртуальной таблице.

Что быстрее: отбор через ССЫЛКА или соединение с таблицей документа?

Отбор через ССЫЛКА быстрее, потому что не требует соединения и проверяет только вид ссылки. Соединение оправдано, когда из документа нужны реквизиты, — в этом случае предварительно приведите составное поле через ВЫРАЗИТЬ.

Работает ли проверка типа для полей регистров и субконто?

Да, операторы ССЫЛКА, ТИПЗНАЧЕНИЯ и ВЫРАЗИТЬ одинаково работают для любых полей составного типа: измерений, ресурсов, реквизитов регистров и значений субконто. Синтаксис не отличается от работы с реквизитами документов.

Итог

Что важно запомнить

Для отбора по виду документа используйте условие «Поле ССЫЛКА Документ.Вид» — это самый быстрый способ. Для доступа к реквизитам составного поля применяйте ВЫРАЗИТЬ вместе с отбором в ГДЕ. Никогда не соединяйте таблицы по неприведённому составному полю и учитывайте пустые значения при проверке типа.