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

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

Как получить список документов за период в 1С

Как получить список документов за период в 1С: выборка, запрос с Границами, журналы документов и динамические списки. Примеры кода, ошибки и проверка результата.

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

Ключевой момент во всех способах — правильная работа с границами периода. В 1С дата хранится с точностью до секунды, поэтому конец периода нужно задавать как конец дня (23:59:59), иначе документы за последний день «обрежутся» до полуночи. Ниже разобраны рабочие варианты кода, типовые ошибки и способы проверить, что выборка полная.

Какой способ выбрать под свою задачу

В 1С есть несколько механизмов получения документов за период, и они не взаимозаменяемы один к одному. Запрос подходит, когда нужны конкретные поля, итоги, соединения с другими таблицами и сортировка. Метод Выбрать() удобен для простого перебора объектов с последующей обработкой каждого документа (например, перепроведение или выгрузка). Журнал документов и динамический список — это интерфейсные инструменты для пользователя, а не для программной обработки.

Если нужно обработать тысячи документов, предпочтителен запрос с выборкой только ссылок и нужных реквизитов: он работает быстрее и не тянет в память полные объекты. Метод Выбрать() с обходом результата создаёт объект документа на каждой итерации, что на больших объёмах ощутимо медленнее.

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

Запрос с МЕЖДУ

Подходит для отчётов, обменов и массовой обработки. Гибкий, быстрый, но требует аккуратности с границами периода.

Метод Выбрать()

Простой перебор документов для обработки объектов. Медленнее запроса на больших объёмах, нет сложной фильтрации.

Журнал документов

Для ручной работы пользователя: отбор по периоду без программирования. Не подходит для автоматической обработки.

Динамический список

Для форм и подборов в управляемом интерфейсе. Требует настройки запроса списка и параметров периода.

Получение списка запросом с параметрами периода

Основной приём — запрос к таблице документа с условием на дату. Параметры передаются через УстановитьПараметр, а конец периода задаётся функцией КонецДня() встроенного языка, чтобы захватить документы до 23:59:59 включительно.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

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

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

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

|ИЗ

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

|ГДЕ

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

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

|

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

| Дата";

Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ДатаНачала));

Запрос.УстановитьПараметр("КонецПериода", КонецДня(ДатаОкончания));

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

Обратите внимание на условие Проведен: оно отсекает непроведённые и помеченные на удаление документы. Если нужны все документы, включая черновики, условие убирают, но тогда в выборку попадут и помеченные на удаление объекты — их можно отфильтровать отдельным условием ПометкаУдаления = ЛОЖЬ.

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

Работа с границами периода: типичная ловушка

Самая частая причина «потерянных» документов — неправильная граница конца периода. Дата в 1С всегда содержит время, и документ, созданный в 14:30 последнего дня периода, не удовлетворяет условию Дата <= ДатаКонца, если ДатаКонца равна полуночи этого дня.

Есть три корректных способа задать конец периода. Первый — КонецДня(ДатаОкончания), самый читаемый. Второй — объект Граница с видом Включая, если документы могут иметь одинаковую дату-время и важна точность до момента времени. Третий — условие Дата < &СледующийДень, где параметр равен началу следующего за периодом дня.

// Вариант с объектом Граница

Запрос.УстановитьПараметр("КонецПериода",

Новый Граница(КонецДня(ДатаОкончания), ВидГраницы.Включая));

// Вариант со строгим неравенством

// В тексте запроса: ГДЕ Дата >= &Начало И Дата < &СледующийДень

Запрос.УстановитьПараметр("СледующийДень", КонецДня(ДатаОкончания) + 1);

Способ со строгим неравенством и следующим днём считается наиболее надёжным: он не зависит от точности представления времени и корректно работает даже если бы точность даты была выше секунды.

Типичные ошибки
01
Передача даты без времени в параметр конца периода — теряются документы последнего дня.
02
Отсутствие отбора по Проведен — в выборку попадают черновики и помеченные на удаление.
03
Получение объектов через ПолучитьОбъект() в цикле там, где достаточно ссылки и реквизитов, — резкое падение производительности.
04
Сравнение даты со строкой вместо параметра типа Дата — запрос падает с ошибкой или возвращает пустой результат.

Перебор документов методом Выбрать()

Менеджер документа имеет метод Выбрать(), который принимает начало и конец периода и возвращает выборку для обхода в цикле. Этот способ проще в написании и подходит, когда каждый документ нужно открыть как объект и что-то с ним сделать.

Выборка = Документы.РеализацияТоваровУслуг.Выбрать(

НачалоДня(ДатаНачала), КонецДня(ДатаОкончания));

Пока Выборка.Следующий() Цикл

Если Выборка.Проведен Тогда

// Обработка документа: Выборка.Ссылка

КонецЕсли;

КонецЦикла;

Внутри цикла доступны реквизиты выборки напрямую, без получения объекта. Обращайтесь к объекту через Выборка.Ссылка.ПолучитьОбъект() только если действительно нужно изменить и записать документ — чтение реквизитов через выборку заметно дешевле.

У метода Выбрать() есть ограничения: нельзя задать произвольный отбор по реквизитам (только период и, в некоторых случаях, отбор по значениям), нет соединений с другими таблицами и группировок. Как только логика усложняется, переходите на запрос.

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

Если задача решается без программирования, используйте журнал документов. Откройте нужный журнал (например, «Продажи» → «Реализация (акты, накладные)» в типовых конфигурациях), нажмите кнопку отбора или установите период в шапке списка. В большинстве типовых журналов есть поля «Дата с» и «по» либо кнопка выбора стандартного периода: день, неделя, месяц, квартал, год.

Для произвольного отбора используйте «Ещё» → «Настроить список» (или «Установить отбор и сортировку» в обычных формах). Там можно добавить условие по дате, организации, контрагенту и другим реквизитам. Настройку отбора можно сохранить как вариант списка, чтобы не повторять её каждый раз.

Полученный список выводится на печать или сохраняется в табличный документ через «Ещё» → «Вывести список». Это быстрый способ получить реестр документов за период без отчётов и обработок.

Порядок действий в пользовательском режиме
  1. 1
    Откройте журнал нужного вида документов.
  2. 2
    Установите период в полях дат или через стандартный период.
  3. 3
    При необходимости добавьте отбор через «Ещё» → «Настроить список».
  4. 4
    Проверьте, что список содержит ожидаемые документы за первый и последний день периода.
  5. 5
    Выведите список в табличный документ, если нужен реестр.

Динамический список с отбором по периоду

В управляемых формах списки документов строятся на динамическом списке — по сути, на запросе, который платформа выполняет автоматически. Если вы разрабатываете собственную форму подбора или обработку со списком документов, период задаётся через параметры запроса динамического списка.

Текст запроса динамического списка задаётся в свойстве «Произвольный запрос» в конфигураторе или программно через СвойстваСписка. Параметры периода устанавливаются через УстановитьЗначениеПараметра объекта Список:

Список.Параметры.УстановитьЗначениеПараметра("НачалоПериода", НачалоДня(ДатаНачала));

Список.Параметры.УстановитьЗначениеПараметра("КонецПериода", КонецДня(ДатаОкончания));

Альтернатива — отбор через ЭлементыОтбора динамического списка, но для дат параметры запроса предпочтительнее: они попадают прямо в условие ГДЕ и используют индекс по дате, тогда как отбор по полю Дата в некоторых случаях работает медленнее на больших таблицах.

Как проверить, что выборка полная

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

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

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

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

Документы за первый день периода
Норма

Присутствуют в выборке с 00:00:00

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

Документы раннего утра первого дня отсутствуют — проверьте параметр начала

Документы за последний день
Норма

Есть документы с временем до 23:59:59

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

Последний день пуст или обрезан — конец периода задан как полночь

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

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

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

Меньше, чем в журнале — лишний отбор или неверные границы

Помеченные на удаление
Норма

Исключены, если не нужны

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

Попадают в выборку и портят итоги

Производительность на больших объёмах

На базах с сотнями тысяч документов выборка за длинный период может выполняться заметно долго. Основные приёмы ускорения: выбирать только нужные поля вместо «*», не вызывать ПолучитьОбъект() без необходимости, ограничивать период до реально требуемого и использовать условие по дате в самом запросе, а не фильтровать результат в коде.

Поле Дата в таблицах документов индексировано, поэтому условие МЕЖДУ по дате работает быстро. А вот функции над датой в условии (например, НАЧАЛОПЕРИОДА(Дата, ДЕНЬ) = &Дата) лишают запрос возможности использовать индекс — избегайте таких конструкций в условиях отбора.

Если выборка нужна регулярно и по фиксированным условиям, рассмотрите виртуальные таблицы регистров вместо сканирования документов: например, итоги по продажам быстрее получить из регистра накопления, чем суммировать табличные части документов.

Итог

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

Для программного получения документов за период используйте запрос с условием МЕЖДУ и параметрами, конец периода задавайте через КонецДня() или строгое неравенство со следующим днём. Для простого перебора подойдёт Выбрать(), для пользовательской работы — журнал документов с отбором. Всегда проверяйте, что документы первого и последнего дня попали в выборку, и не забывайте про отбор по проведённости и пометке удаления.

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

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

Потому что дата без времени интерпретируется как 00:00:00, и условие Дата <= &КонецПериода отсекает всё, что позже полуночи. Передавайте в параметр КонецДня(ДатаОкончания) или используйте условие Дата < &СледующийДень с датой, следующей за концом периода.

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

Используйте ОБЪЕДИНИТЬ ВСЕ с отдельными подзапросами к каждой таблице документов, либо запрос к журналу документов, если нужные виды входят в один журнал. При объединении приведите поля к одинаковому составу и порядку.

Нужно ли включать помеченные на удаление документы?

Зависит от задачи. Для отчётности и обменов их обычно исключают условием ПометкаУдаления = ЛОЖЬ. Для аудита или восстановления данных помеченные документы наоборот выбирают отдельно. Условие Проведен автоматически исключает помеченные, так как проведённый документ не может быть помечен на удаление.

Чем отличается Выбрать() от запроса по скорости?

Метод Выбрать() на каждой итерации формирует выборку по одному документу и при обращении к объекту читает его целиком. Запрос получает только указанные поля одним обращением к базе. На больших объёмах запрос с выборкой ссылок и реквизитов работает заметно быстрее и меньше нагружает память.

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

Добавьте в условие запроса отбор по реквизиту: И Организация = &Организация. Параметр передаётся через УстановитьПараметр как ссылка на элемент справочника. В пользовательском режиме тот же результат даёт отбор в журнале через «Настроить список».

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

Да, программный запрос к таблице документа проверяет права на сам вид документа, а не на журнал. Если у пользователя есть право чтения документа, запрос вернёт данные. При работе под ограниченными правами учитывайте также RLS — ограничение доступа на уровне записей, которое может скрывать часть строк.