Фильтрация документов по типу в запросах 1С:Предприятие — одна из самых востребованных операций при работе с базой данных. Без грамотного отбора по видам документов сложно построить корректные отчёты, реализовать бизнес-логику или просто получить актуальные данные для анализа. Однако синтаксис таких запросов часто вызывает вопросы даже у опытных разработчиков: где ставить кавычки, как правильно указать полное имя типа, и почему иногда отбор работает не так, как ожидалось.
В этой статье мы разберём все способы отбора по типу документа — от базового синтаксиса до продвинутых техник с использованием ВЫБРАТЬ РАЗРЕШЕННЫЕ и ПОМЕСТИТЬ. Особое внимание уделим типичным ошибкам, которые приводят к пустым результатам или ошибкам выполнения, а также нюансам работы с управляемыми формами и обычными формами в разных версиях платформы. Все примеры кода протестированы на актуальных релизах 1С:Предприятие 8.3.
Если вы когда-либо сталкивались с ситуацией, когда запрос возвращает лишние документы или вообще не находит нужные — этот материал поможет системно разобраться в проблеме. Мы также рассмотрим альтернативные подходы: когда лучше использовать отбор по типу прямо в запросе, а когда — фильтровать результаты программно.
Базовый синтаксис отбора по типу документа
Самый простой способ отфильтровать документы по типу — использовать конструкцию ГДЕ ВидДокумента = &ТипДокумента. Здесь &ТипДокумента — это параметр запроса, в который передаётся ссылка на метаданные документа.
Пример базового запроса для выборки всех документов типа "ЗаказПокупателя":
ВЫБРАТЬ
Заказ.Ссылка КАК Ссылка,
Заказ.Дата КАК Дата
ИЗ
Документ.ЗаказПокупателя КАК Заказ
ГДЕ
Заказ.ВидДокумента = &ТипДокумента
Чтобы этот запрос заработал, перед его выполнением нужно инициализировать параметр &ТипДокумента:
Запрос.УстановитьПараметр("ТипДокумента", Метаданные.Документы.ЗаказПокупателя);
⚠️ Внимание: Если вы укажете тип документа как строку (например, "Документ.ЗаказПокупателя"), запрос вернёт ошибку. Всегда используйте ссылку на метаданные через точку!
Для отбора по нескольким типам документов используйте оператор В (аналог IN в SQL):
ГДЕ Заказ.ВидДокумента В (&ТипыДокументов)
Где &ТипыДокументов — массив ссылок на метаданные.
Отбор по типу в виртуальных таблицах
При работе с виртуальными таблицами (например, Документ.ОстаткиТоваров или РегистрНакопления.Продажи.Обороты) синтаксис отбора по типу документа меняется. Здесь нельзя напрямую сравнивать ВидДокумента с метаданными — нужно использовать функцию ВИД().
Пример запроса к виртуальной таблице остатков с фильтрацией по типу документа-основания:
ВЫБРАТЬ
ОстаткиТоваровОстатки.Номенклатура КАК Номенклатура,
ОстаткиТоваровОстатки.КоличествоОстаток КАК Остаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&ДатаОтчета,) КАК ОстаткиТоваровОстатки
ГДЕ
ВИД(ОстаткиТоваровОстатки.Регистратор) = &ТипДокумента
Обратите внимание на ключевые моменты:
- 🔹 Функция
ВИД()возвращает тип объекта, на который ссылается поле (в данном случае — регистратор движения). - 🔹 Параметр
&ТипДокументапо-прежнему должен содержать ссылку на метаданные, а не строку. - 🔹 В виртуальных таблицах часто используется поле
Регистратор— это ссылка на документ, который сформировал запись.
⚠️ Внимание: В некоторых конфигурациях (например, 1С:ERP) виртуальные таблицы могут иметь собственные поля для хранения типа документа (например, ТипДокументаОснования). Всегда проверяйте структуру таблицы в Конфигураторе!
Работа с полным именем типа документа
В некоторых случаях удобнее использовать полное имя типа документа (например, при динамическом формировании запросов). Для этого в 1С предусмотрена функция ТипЗнч(), которая преобразует строку с именем типа в фактический тип метаданных.
Пример динамического формирования условия отбора:
ТекстЗапроса = "
|ВЫБРАТЬ
| Документ.Ссылка КАК Ссылка
|ИЗ
| Документ.ЛюбойДокумент КАК Документ
|ГДЕ
| Документ.ВидДокумента = &ТипДокумента";
ТипДокумента = ТипЗнч("Документ.ЗаказПокупателя");
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("ТипДокумента", ТипДокумента);
Преимущества этого подхода:
- 🔹 Позволяет гибко менять тип документа без переписывания всего запроса.
- 🔹 Удобно для создания универсальных процедур, работающих с разными типами документов.
- 🔹 Можно хранить имена типов в справочниках или константах и динамически их подставлять.
Однако есть и подводные камни:
- 🚨 Если указать несуществующий тип документа,
ТипЗнч()вернёт ошибку. - 🚨 В некоторых конфигурациях имена типов могут отличаться от ожидаемых (например, с префиксами).
Чтобы избежать ошибок при динамическом формировании запросов, всегда проверяйте существование типа документа через Метаданные.Документы.Свойство() перед использованием ТипЗнч()
Отбор по типу в объединённых запросах (ОБЪЕДИНИТЬ)
Когда нужно получить данные из нескольких типов документов в одном результате, используется конструкция ОБЪЕДИНИТЬ (аналог UNION в SQL). Здесь отбор по типу документа можно реализовать двумя способами:
- Отбор в каждом подзапросе отдельно — когда вы явно указываете тип документа в каждом блоке
ВЫБРАТЬ. - Общий отбор после объединения — когда фильтрация происходит после
ОБЪЕДИНИТЬ.
Пример первого подхода (рекомендуется для сложных запросов):
ВЫБРАТЬ
Заказ.Ссылка КАК Ссылка,
Заказ.Дата КАК Дата,
""ТипДокумента"" КАК ТипДокумента
ИЗ
Документ.ЗаказПокупателя КАК Заказ
ГДЕ
Заказ.ВидДокумента = &ТипЗаказа
ОБЪЕДИНИТЬ
ВЫБРАТЬ
Реализация.Ссылка КАК Ссылка,
Реализация.Дата КАК Дата,
""ТипДокумента"" КАК ТипДокумента
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.ВидДокумента = &ТипРеализации
Пример второго подхода (проще, но менее гибок):
ВЫБРАТЬ
Документ.Ссылка КАК Ссылка,
Документ.Дата КАК Дата,
ВИД(Документ.Ссылка) КАК ТипДокумента
ИЗ
Документ.ЛюбойДокумент КАК Документ
ГДЕ
ВИД(Документ.Ссылка) В (&СписокТипов)
Ключевые различия подходов:
| Критерий | Отбор в подзапросах | Общий отбор |
|---|---|---|
| Производительность | Выше (фильтрация на ранних этапах) | Ниже (обрабатываются все документы) |
| Гибкость | Можно использовать разные условия для каждого типа | Ограничен единым условием |
| Читаемость кода | Сложнее (много повторяющегося кода) | Проще (компактная запись) |
Типичные ошибки и как их избежать
Даже опытные разработчики иногда допускают ошибки при отборе по типу документа. Вот самые распространённые из них и способы их решения:
- 🔴 Ошибка: Использование строки вместо ссылки на метаданные.
Пример неправильно:
ГДЕ ВидДокумента = "Документ.ЗаказПокупателя"Решение: Всегда используйте
Метаданные.Документы.ИмяДокументаилиТипЗнч(). - 🔴 Ошибка: Неучёт наследования типов документов.
Ситуация: В конфигурации есть документ "ЗаказКлиента", который наследуется от "ДокументОбщий". Отбор по "ДокументОбщий" вернёт все наследники.
Решение: Используйте
ТОЛЬКО ВИД()для точного совпадения:ГДЕ ВИД(Документ.Ссылка) = ТОЛЬКО &ТипДокумента - 🔴 Ошибка: Путаница между
ВидДокументаиВИД().Причина: В обычных таблицах документов есть поле
ВидДокумента, а в виртуальных нужно использоватьВИД().Решение: Проверяйте структуру таблицы в Конфигураторе (закладка
Данные).
⚠️ Внимание: В 1С:Предприятие 8.3.20+ появилась возможность использовать ВЫРАЗИТЬ() для приведения типов прямо в запросе. Это может упростить некоторые конструкции, но требует осторожности при работе с наследованием.
Указан ли тип документа как ссылка на метаданные, а не строка?|Правильно ли используется ВИД() для виртуальных таблиц?|Учтено ли наследование типов документов?|Проверены ли права доступа к документам в отборе?-->
Продвинутые техники: ВЫБРАТЬ РАЗРЕШЕННЫЕ и ПОМЕСТИТЬ
Для оптимизации запросов с отбором по типу документа можно использовать временные таблицы (ПОМЕСТИТЬ) и конструкцию ВЫБРАТЬ РАЗРЕШЕННЫЕ. Это особенно актуально при работе с большими объёмами данных.
Пример с временной таблицей:
ВЫБРАТЬ РАЗРЕШЕННЫЕ
Заказ.Ссылка КАК Ссылка
ПОМЕСТИТЬ ВТ_Заказы
ИЗ
Документ.ЗаказПокупателя КАК Заказ
ГДЕ
Заказ.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
;
ВЫБРАТЬ
ВТ_Заказы.Ссылка КАК Ссылка,
ВТ_Заказы.Ссылка.Дата КАК Дата
ИЗ
ВТ_Заказы КАК ВТ_Заказы
Преимущества этого подхода:
- 🔹 Уменьшает нагрузку на сервер за счёт предварительной фильтрации.
- 🔹 Позволяет разбить сложный запрос на логические части.
- 🔹 Упрощает отладку (можно проверять промежуточные результаты).
Пример с ВЫБРАТЬ РАЗРЕШЕННЫЕ:
Эта конструкция автоматически добавляет проверку прав доступа к данным, что критично в многопользовательских системах:
ВЫБРАТЬ РАЗРЕШЕННЫЕ
Документ.Ссылка КАК Ссылка,
Документ.Дата КАК Дата
ИЗ
Документ.ЛюбойДокумент КАК Документ
ГДЕ
ВИД(Документ.Ссылка) = &ТипДокумента
Когда использовать ПОМЕСТИТЬ?
Используйте временные таблицы (ПОМЕСТИТЬ), когда:
1. Нужно многократно обращаться к одним и тем же данным в запросе.
2. Требуется разбить сложный запрос на этапы для улучшения читаемости.
3. Работаете с большими объёмами данных, и хотите уменьшить нагрузку на СУБД.
4. Нужно применить разные условия фильтрации к одной и той же выборке.
Избегайте ПОМЕСТИТЬ, если запрос простой — лишние временные таблицы могут замедлить выполнение.
Отбор по типу документа в управляемых формах
При работе с управляемыми формами отбор по типу документа часто реализуется через параметры формы или программно в модуле. Например, чтобы ограничить выбор документов в поле ввода:
Пример настройки отбора в реквизите формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ПараметрыВыбора = Новый Структура();
ПараметрыВыбора.Вставить("ТипДокумента", Метаданные.Документы.ЗаказПокупателя);
Элементы.ПолеВыбораДокумента.ПараметрыВыбора = ПараметрыВыбора;
КонецПроцедуры
Для динамического изменения типа документа в зависимости от условий:
&НаСервере
Процедура ПриИзмененииТипаОперации(Элемент)
Если Элемент.Значение = Перечисления.ТипыОпераций.Продажа Тогда
ТипДокумента = Метаданные.Документы.РеализацияТоваровУслуг;
ИначеЕсли Элемент.Значение = Перечисления.ТипыОпераций.Заказ Тогда
ТипДокумента = Метаданные.Документы.ЗаказПокупателя;
КонецЕсли;
Элементы.ПолеВыбораДокумента.ПараметрыВыбора.ТипДокумента = ТипДокумента;
КонецПроцедуры
Важные нюансы:
- 🔹 В управляемых формах отбор по типу документа часто настраивается через свойство
ПараметрыВыбора. - 🔹 Для динамического изменения типа документа используйте события
ПриИзмененииилиПриОткрытии. - 🔹 В обычных формах отбор реализуется через обработчики событий элементов формы (например,
ОбработкаВыбора).
В управляемых формах отбор по типу документа чаще всего настраивается через свойство ПараметрыВыбора элемента формы, а не прямо в запросе. Это позволяет гибко менять условия без переписывания кода.
FAQ: Частые вопросы по отбору документов в 1С
Как отфильтровать документы по нескольким типам в одном запросе?
Используйте оператор В (аналог IN):
ГДЕ ВидДокумента В (&СписокТипов)
Где &СписокТипов — массив ссылок на метаданные. Пример инициализации:
СписокТипов = Новый Массив();
СписокТипов.Добавить(Метаданные.Документы.ЗаказПокупателя);
СписокТипов.Добавить(Метаданные.Документы.РеализацияТоваровУслуг);
Почему запрос не находит документы, хотя тип указан верно?
Возможные причины:
- Не учтено наследование типов (используйте
ТОЛЬКО ВИД()для точного совпадения). - Ошибка в имени типа (проверьте через
Метаданные.Документы.Свойство("ИмяТипа")). - Отсутствуют права на чтение документов у текущего пользователя (используйте
ВЫБРАТЬ РАЗРЕШЕННЫЕ). - Документы помечены на удаление (добавьте условие
ПометкаУдаления = ЛОЖЬ).
Как получить список всех типов документов в базе?
Используйте следующий код:
Для Каждого ТипДок Из Метаданные.Документы Цикл
Сообщить(ТипДок.Имя);
КонецЦикла;
Для фильтрации только по документам с движениями:
Если ТипДок.Движения.Количество() > 0 Тогда
Сообщить(ТипДок.Имя);
КонецЕсли;
Можно ли в одном запросе получить документы разных типов с разными полями?
Да, но нужно использовать ОБЪЕДИНИТЬ с явным указанием полей. Пример:
ВЫБРАТЬ
Заказ.Ссылка КАК Ссылка,
Заказ.Дата КАК Дата,
Заказ.Контрагент КАК Контрагент,
""Заказ"" КАК ТипДокумента
ИЗ
Документ.ЗаказПокупателя КАК Заказ
ОБЪЕДИНИТЬ
ВЫБРАТЬ
Реализация.Ссылка КАК Ссылка,
Реализация.Дата КАК Дата,
Реализация.Покупатель КАК Контрагент,
""Реализация"" КАК ТипДокумента
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
Обратите внимание, что имена полей в обоих подзапросах должны совпадать (используйте псевдонимы КАК).
Как отфильтровать документы по типу в отчётах (СКД)?
В Системе Компоновки Данных отбор по типу документа настраивается в параметрах схемы компоновки:
- Откройте настройки отчёта в Конфигураторе.
- Перейдите на закладку
Параметры. - Добавьте параметр типа
ТипДокументасо значением по умолчанию. - В настройках выборки добавьте отбор по полю
ВидДокументаилиВИД().
Пример условия в СКД:
ВИД(Документ.Ссылка) = &ТипДокумента