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