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