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

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

1С: как выбрать документы на дату

Как выбрать документы на конкретную дату в 1С: запрос с отбором по периоду, ВыборкаИзРезультатаЗапроса, УстановитьОтбор в журнале, типовые ошибки и примеры кода.

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

Принципиально важный момент: в 1С документ хранит не просто дату, а дату со временем (с точностью до секунды). Поэтому условие «равно дате» почти всегда работает не так, как ожидает пользователь, — документ, проведенный в 14:35, не попадет в отбор «Дата = 01.03.0001 00:00:00». Правильный подход — отбор по диапазону от начала до конца дня.

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

Как 1С хранит дату документа и почему это важно

Поле «Дата» у документа в 1С — это момент времени, включающий часы, минуты и секунды. Именно эта величина определяет позицию документа в последовательности и влияет на проведение. Когда пользователь вводит в форме «15.03», система фактически записывает «15.03 00:00:00», а реальный документ, созданный днем, имеет время вроде «15.03 14:22:47».

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

Для получения границ дня во встроенном языке есть функции НачалоДня(Дата) и КонецДня(Дата). Вторая возвращает 23:59:59 указанной даты, что полностью покрывает сутки. В языке запросов аналогичные вычисления выполняются через параметры, переданные из кода, или через функции НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА.

Выбор документов на дату в журнале без программирования

Простейший сценарий — найти документы за нужный день прямо в интерфейсе. Откройте журнал документов (например, «Покупки — Поступления товаров» или «Все документы» в разделе операций) и нажмите кнопку «Ещё — Установить период» либо воспользуйтесь быстрым отбором по периоду, если он выведен на панель журнала.

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

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

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

Запрос: выбрать документы на конкретную дату

В коде самый универсальный способ — запрос к таблице документа с условием по периоду. Параметры начала и конца дня вычисляются заранее и передаются в запрос, что исключает ошибки со временем:

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

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

"ВЫБРАТЬ

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

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

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

|ИЗ

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

|ГДЕ

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

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

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

Запрос.УстановитьПараметр("КонецДня", КонецДня(НужнаяДата));

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

Пока Результат.Следующий() Цикл

// обработка Результат.Документ

КонецЦикла;

Обратите внимание на условие Проведен: часто для обработки нужны только проведенные документы. Если нужны все — включая помеченные на удаление и непроведенные — условие убирают, но тогда в выборку попадут и «мусорные» объекты, что надо учитывать в логике обработки.

Альтернатива МЕЖДУ — функции периода прямо в тексте запроса: ГДЕ РеализацияТоваровУслуг.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ) И КОНЕЦПЕРИОДА(&Дата, ДЕНЬ). Тогда достаточно передать один параметр с датой. Оба варианта равнозначны; выбор — вопрос читаемости кода.

Выборка по нескольким видам документов

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

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

Программная выборка через метод Выбрать()

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

Выборка = Документы.ПриходныйКассовыйОрдер.Выбрать(

НачалоДня(НужнаяДата), КонецДня(НужнаяДата));

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

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

// работа с Выборка.Ссылка

КонецЕсли;

КонецЦикла;

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

Третий и четвертый параметры Выбрать() позволяют задать отбор по реквизитам и порядок сортировки. Например, Выбрать(НачалоДня(Д), КонецДня(Д), Отбор, "Дата Возр"), где Отбор — структура вида Новый Структура("Организация", ОрганизацияСсылка). Отбор работает только по реквизитам, для которых в конфигураторе включена индексация, иначе метод выдаст ошибку.

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

Отбор в журнале

Подходит пользователю без программирования; ограничение — нельзя использовать в автоматической обработке

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

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

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

Быстрый короткий код для простого обхода; ограничен набор полей и отбор только по индексированным реквизитам

Консоль запросов

Удобна для разового анализа и отладки условия; нужен доступ к внешней обработке или встроенной консоли

Проверка результата и контроль полноты выборки

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

Проверьте крайние документы: самый ранний должен быть не раньше 00:00:00 нужной даты, самый поздний — не позже 23:59:59. Если в выборку попали документы соседних дат — в условии ошибка, чаще всего перепутаны параметры или использовано равенство вместо диапазона.

Для программной проверки пустого результата используйте РезультатЗапроса.Пустой() до начала обхода. Это позволит корректно обработать ситуацию «документов за дату нет» и не выполнять лишние действия.

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

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

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

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

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

Выборка меньше — проверьте границы дня и условие Проведен

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

Все даты внутри суток нужной даты

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

Есть документы соседних дат — ошибка в параметрах периода

Время в условии отбора
Норма

Используются НачалоДня и КонецДня или НАЧАЛОПЕРИОДА/КОНЕЦПЕРИОДА

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

Сравнение Дата = &Дата без времени — теряются документы, созданные днем

Типичные ошибки при отборе по дате

Самая распространенная ошибка — условие ГДЕ Документ.Дата = &Дата, где параметр содержит дату без времени. Запрос вернет только документы с временем 00:00:00, а их в реальной базе почти нет. Симптом: «запрос ничего не находит, хотя документы в журнале есть».

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

Третья ошибка — игнорирование часовых поясов в клиент-серверных базах. Сеансовая дата на сервере может отличаться от даты пользователя в другом часовом поясе. Если обработка выполняется на сервере, передавайте дату явно с клиента, а не берите ТекущаяДатаСеанса() как «сегодня» пользователя.

Типичные ошибки
01
Условие Дата = &Дата без времени — находятся только документы в 00:00:00, остальные теряются
02
Использование КонецДня через Дата + 86400 вручную — риск захватить 00:00:00 следующего дня при ошибке в расчете
03
Отбор по неиндексированному реквизиту в методе Выбрать() — ошибка выполнения
04
Забытое условие Проведен — в обработку попадают помеченные на удаление и черновики
05
Сравнение строки с датой — несоответствие типов и пустой результат

Ограничения и когда нужна осторожность

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

Если обработка не только читает, но и изменяет найденные документы (перепроведение, установка пометки удаления), обязательно делайте резервную копию или используйте транзакцию с возможностью отката. Ошибка в условии отбора в этом случае затронет не те документы, и восстановление потребует вмешательства администратора.

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

Итог

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

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

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

Почему запрос с условием «Дата = &Дата» ничего не находит?

Потому что у документов в дате записано время, а параметр содержит 00:00:00. Равенство не выполняется. Замените условие на диапазон: Дата МЕЖДУ НачалоДня(&Дата) И КонецДня(&Дата) либо используйте НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА в тексте запроса.

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

Вычислите вчерашнюю дату: Вчера = НачалоДня(ТекущаяДатаСеанса()) - 1; — вычитание секунды из начала сегодняшнего дня дает конец вчерашнего. Затем передайте НачалоДня(Вчера) и КонецДня(Вчера) в параметры запроса или метода Выбрать().

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

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

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

Нажмите «Ещё — Установить период» и выберите стандартный вариант «Сегодня». В большинстве типовых конфигураций панель быстрого выбора периода уже выведена над списком — достаточно одного клика по кнопке периода.

Что вернет метод Выбрать(), если границы периода перепутаны местами?

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

Нужно ли учитывать часовой пояс при отборе по дате?

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