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