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