К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как в запросе 1С выбрать все документы

Как в запросе 1С выбрать все документы: синтаксис ВЫБРАТЬ, выборка всех типов документов, отбор по периоду и организации, типичные ошибки и примеры кода.

Задача выбрать все документы в запросе 1С встречается при написании отчётов, обработок свёртки данных, выгрузок и регламентных заданий. В зависимости от постановки задачи под «всеми документами» понимают либо все документы одного вида (например, все «Поступления товаров»), либо документы нескольких видов, либо вообще все документы конфигурации. Каждый сценарий решается своим синтаксисом.

Базовый инструмент — оператор ВЫБРАТЬ с обращением к таблице документа через конструкцию Документ.ИмяДокумента. Если нужны документы всех видов сразу, применяют объединение запросов через ОБЪЕДИНИТЬ ВСЕ либо перебор метаданных с динамическим формированием текста запроса. Ниже разобраны все подходы с готовыми примерами кода.

Выбор всех документов одного вида

Самый частый случай — получить все документы конкретного вида без отборов. Запрос обращается к таблице документа по имени, заданному в конфигураторе:

ВЫБРАТЬ

РеализацияТоваровУслуг.Ссылка КАК Ссылка,

РеализацияТоваровУслуг.Номер КАК Номер,

РеализацияТоваровУслуг.Дата КАК Дата,

РеализацияТоваровУслуг.Проведен КАК Проведен

ИЗ

Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

Такой запрос вернёт все записи таблицы документа, включая помеченные на удаление и непроведённые. Это важно: язык запросов по умолчанию не фильтрует помеченные объекты, в отличие от многих типовых отчётов. Если нужны только «живые» документы, добавьте условие ГДЕ НЕ РеализацияТоваровУслуг.ПометкаУдаления.

Псевдоним таблицы (в примере — РеализацияТоваровУслуг) не обязателен, но он делает запрос читаемее и позволяет избежать неоднозначности при соединениях. Поле Ссылка — ключевое: через него документ связывается с другими таблицами и движениями.

Отбор документов по периоду, организации и другим условиям

На практике «все документы» почти всегда означает «все в рамках условий». Период ограничивают через параметры, чтобы запрос можно было переиспользовать:

ВЫБРАТЬ

ПоступлениеТоваров.Ссылка КАК Ссылка,

ПоступлениеТоваров.Контрагент КАК Контрагент,

ПоступлениеТоваров.СуммаДокумента КАК Сумма

ИЗ

Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваров

ГДЕ

ПоступлениеТоваров.Дата МЕЖДУ &НачалоПериода И &КонецПериода

И ПоступлениеТоваров.Организация = &Организация

И ПоступлениеТоваров.Проведен

УПОРЯДОЧИТЬ ПО

ПоступлениеТоваров.Дата

Параметры передаются в объект запроса через Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ДатаНачала)). Для верхней границы периода используйте КонецДня(), иначе документы последнего дня, созданные после полуночи, выпадут из выборки — одна из самых частых причин «потерянных» документов.

Отбор по проведённости (Проведен = ИСТИНА) уместен, когда анализируются только фактические хозяйственные операции. Для задач аудита, наоборот, часто нужны именно непроведённые или помеченные документы — тогда условие инвертируется.

Порядок действий
  1. 1
    Определите вид документа и нужные поля
  2. 2
    Напишите запрос с секцией ГДЕ и параметрами периода
  3. 3
    Установите параметры через УстановитьПараметр, используя КонецДня для верхней границы
  4. 4
    Выполните запрос и проверьте количество строк в выборке
  5. 5
    Сравните результат с журналом документов в пользовательском режиме

Как выбрать документы всех видов сразу

Когда требуется выгрузить вообще все документы информационной базы (например, для аудита или миграции), статический запрос не подойдёт: видов документов много, и их состав меняется при обновлении конфигурации. Решение — перебрать коллекцию метаданных и построить запрос динамически:

ТекстЗапроса = "";

Для Каждого ДокументМД Из Метаданные.Документы Цикл

Если Не ПустаяСтрока(ТекстЗапроса) Тогда

ТекстЗапроса = ТекстЗапроса + "

|ОБЪЕДИНИТЬ ВСЕ

|";

КонецЕсли;

ТекстЗапроса = ТекстЗапроса + "ВЫБРАТЬ

| Т.Ссылка КАК Ссылка,

| """ + ДокументМД.Имя + """ КАК ВидДокумента

|ИЗ

| Документ." + ДокументМД.Имя + " КАК Т";

КонецЦикла;

Запрос = Новый Запрос(ТекстЗапроса);

Результат = Запрос.Выполнить().Выгрузить();

Оператор ОБЪЕДИНИТЬ ВСЕ склеивает выборки без удаления дублей — это быстрее, чем просто ОБЪЕДИНИТЬ, а дубли здесь невозможны по определению, так как ссылки разных видов не пересекаются. В поле «ВидДокумента» записывается имя вида строкой, чтобы результат можно было группировать и фильтровать.

У этого подхода есть ограничение: у документов разных видов разный набор реквизитов, поэтому в объединённом запросе доступны только общие поля — Ссылка, Номер, Дата, Проведен, ПометкаУдаления. Специфические реквизиты (Контрагент, Склад и т.п.) придётся получать отдельными запросами по каждому виду.

Альтернатива: выборка через журналы документов

Если нужные виды документов входят в один журнал (например, «Складские документы» или «Документы по контрагенту»), запрос можно написать к таблице журнала: ИЗ Журнал.СкладскиеДокументы. Это проще, чем объединение, и сразу даёт графы журнала.

Ограничение очевидно: журнал включает только те виды, которые в него добавлены в конфигураторе, и только те графы, которые определил разработчик. Для полной выборки по всем видам журналы не подходят — только перебор метаданных.

Сравнение вариантов

Запрос к Документ.Имя

Один вид документа, полный доступ к реквизитам. Основной вариант для отчётов и обработок.

ОБЪЕДИНИТЬ ВСЕ по метаданным

Все виды документов сразу, но только общие поля и высокая нагрузка на больших базах.

Запрос к журналу

Несколько заранее определённых видов, простой синтаксис, но состав жёстко задан в конфигурации.

Проверка результата и производительность

После выполнения запроса убедитесь, что выборка не пуста и содержит ожидаемое число строк. Быстрый способ — выгрузить результат в таблицу значений и посмотреть Результат.Количество(), а затем сверить с количеством документов в журнале пользовательского режима за тот же период.

Для отладки удобна консоль запросов (в типовых конфигурациях на БСП она входит в состав инструментов разработчика). В ней видно текст запроса, параметры и результат без написания обслуживающего кода.

По производительности: запрос без индексированных отборов по большой таблице приведёт к полному сканированию. Поля Дата, Номер, Ссылка, Проведен, ПометкаУдаления индексированы платформой по умолчанию, поэтому отборы по ним работают быстро. Отборы по неиндексированным реквизитам на таблицах в сотни тысяч документов могут занимать заметное время.

Контрольные точки

Как проверить результат

Количество строк выборки
Норма

Совпадает с числом документов в журнале за тот же период с теми же отборами

Тревожный признак

Строк меньше — проверьте границы периода и КонецДня

Состав документов
Норма

Есть документы с любым статусом, если отборов нет

Тревожный признак

Отсутствуют помеченные или непроведённые, хотя должны быть

Время выполнения
Норма

Запрос отрабатывает за секунды

Тревожный признак

Запрос «висит» — вероятно, отбор по неиндексированному полю или объединение десятков таблиц

Типичные ошибки при выборке всех документов

Первая группа ошибок связана с периодом: верхняя граница без КонецДня() отсекает документы последнего дня, а сравнение даты с параметром через равенство почти никогда не срабатывает, потому что дата документа хранит время с точностью до секунды.

Вторая группа — неожиданный состав выборки: разработчик забывает, что запрос возвращает помеченные на удаление документы, и получает лишние строки в отчёте. Обратная ситуация — лишний отбор Проведен = ИСТИНА, из-за которого «пропадают» черновики.

Третья группа — ошибки динамических запросов: опечатка в имени документа при конкатенации строк приводит к ошибке «Таблица не найдена» уже в момент выполнения, а не при сохранении модуля. Используйте имена из Метаданные.Документы, а не литералы, где это возможно.

Типичные ошибки
01
Верхняя граница периода без КонецДня — документы последнего дня не попадают в выборку
02
Забытый отбор по ПометкаУдаления — в отчёт попадают удалённые документы
03
Сравнение даты через равенство вместо МЕЖДУ — условие почти никогда не выполняется
04
ОБЪЕДИНИТЬ вместо ОБЪЕДИНИТЬ ВСЕ — лишняя сортировка и удаление дублей замедляют запрос
05
Обращение к реквизиту, которого нет у части объединяемых видов — ошибка выполнения запроса
Итог

Что важно запомнить

Все документы одного вида выбираются запросом к таблице Документ.ИмяДокумента; все виды сразу — динамическим объединением через метаданные или журналом. Всегда контролируйте пометку удаления, проведённость и границы периода, а результат сверяйте с журналом документов.

Частые вопросы

Как выбрать только проведённые документы?

Добавьте в секцию ГДЕ условие Документ.Проведен = ИСТИНА (или просто Документ.Проведен). Поле Проведен индексировано, поэтому такой отбор не замедляет запрос.

Как получить все документы, в которых участвует конкретный контрагент?

Единого запроса «по всем видам с реквизитом Контрагент» нет: нужно объединить выборки только тех видов, у которых такой реквизит есть, либо использовать критерий отбора, если он настроен в конфигурации (например, типовой критерий «ДокументыПоКонтрагенту»).

Можно ли выбрать документы вместе с их движениями по регистрам?

Да, через левое соединение таблицы документа с таблицей регистра по условию Регистр.Регистратор = Документ.Ссылка. Учтите, что один документ даст несколько строк результата — по числу записей в регистре.

Почему запрос не видит документ, который есть в журнале?

Чаще всего дело в границах периода (время у даты документа), в отборе по организации или в ограничении прав доступа на уровне записей (RLS) — под пользователем без полных прав часть документов скрывается автоматически.

Как выбрать все документы за текущий день?

Передайте параметры &Начало = НачалоДня(ТекущаяДатаСеанса()) и &Конец = КонецДня(ТекущаяДатаСеанса()) и используйте условие Дата МЕЖДУ &Начало И &Конец. Используйте ТекущаяДатаСеанса(), а не ТекущаяДата(), чтобы избежать расхождений часовых поясов клиента и сервера.

Что быстрее: запрос или перебор через Выбрать() менеджера документа?

Для чтения большого объёма данных запрос почти всегда эффективнее: он выполняется на сервере СУБД и возвращает только нужные поля. Метод Документы.Имя.Выбрать() оправдан, когда по каждому документу нужно выполнить объектную логику (провести, изменить, удалить).