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