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