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