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

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

1С запрос: как получить текущую дату

Как получить текущую дату в запросе 1С: передача через параметр ТекущаяДата(), функция ТекущаяДатаСеанса(), сравнение с датами документов, типичные ошибки и примеры кода.

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

Базовая связка выглядит так: в модуле вызывается функция ТекущаяДатаСеанса(), её результат присваивается параметру запроса, а в тексте запроса параметр используется как обычное значение — в условии ГДЕ, в конструкции ВЫБОР или в списке полей. Такой подход работает на любой версии платформы 8.3 и не зависит от режима совместимости.

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

Почему в запросе нельзя написать функцию текущей даты напрямую

Язык запросов 1С — это декларативный язык выборки данных, а не полноценный язык программирования. Он умеет обращаться к таблицам базы данных, вычислять выражения над полями и параметрами, но не содержит функций работы с системным временем. Попытка написать ТекущаяДата() в тексте запроса приведёт к ошибке «Функция не найдена» ещё на этапе проверки текста.

Единственное исключение — конструкция &ТекущаяДата, которая является не функцией, а параметром. Значение параметра обязан предоставить разработчик из встроенного языка. Если параметр не установить, запрос выполнится с ошибкой «Параметр не определён».

Это ограничение осознанное: запрос выполняется на сервере СУБД, и платформа перекладывает ответственность за определение «текущего момента» на прикладной код, где разработчик сам выбирает — серверное время, клиентское время или дату сеанса в конкретном часовом поясе.

Основной способ: передача текущей даты параметром

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

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

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

"ВЫБРАТЬ

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

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

|ИЗ

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

|ГДЕ

| РеализацияТоваровУслуг.Дата <= &ТекущаяДата

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

Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДатаСеанса());

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

Здесь параметр &ТекущаяДата участвует в условии отбора: выбираются только проведённые документы с датой не позже текущего момента. Точно так же параметр можно вывести как поле, например для подстановки в отчёт:

"ВЫБРАТЬ

| &ТекущаяДата КАК ДатаФормирования,

| Товары.Ссылка КАК Номенклатура

|ИЗ

| Справочник.Номенклатура КАК Товары"

Порядок действий
  1. 1
    Получите дату в коде: ТекущаяДатаСеанса()
  2. 2
    Создайте объект Запрос и задайте текст с параметром &ТекущаяДата
  3. 3
    Вызовите Запрос.УстановитьПараметр("ТекущаяДата"..) до выполнения
  4. 4
    Выполните запрос и проверьте результат в отладчике или консоли запросов

ТекущаяДатаСеанса, ТекущаяДата и УниверсальноеВремя: что выбрать

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

ТекущаяДатаСеанса() — рекомендуемый вариант для серверного кода. Возвращает дату и время компьютера-сервера, приведённые к часовому поясу текущего сеанса. Именно эта функция используется в типовых конфигурациях для установки дат документов.

ТекущаяДата() возвращает время того компьютера, где исполняется код. На сервере — серверное, на клиенте — клиентское. Если у пользователя сбиты часы, отбор по такой дате даст неверный результат. В файловой базе разницы между функциями практически нет, в клиент-серверной — есть.

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

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

ТекущаяДатаСеанса()

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

ТекущаяДата()

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

УниверсальноеВремя()

Время UTC. Нужно для обменов и интеграций, для обычных отборов избыточно.

Типовые сценарии использования текущей даты в запросе

Отбор документов за текущий день

Частая задача — выбрать документы «за сегодня». Здесь Правильно задавать границы дня:

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

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

// В тексте запроса:

// ГДЕ Документ.Дата МЕЖДУ &НачалоДня И &КонецДня

Получение остатков и цен на текущий момент

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

"ВЫБРАТЬ

| Остатки.Номенклатура КАК Номенклатура,

| Остатки.КоличествоОстаток КАК Остаток

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки(&ТекущаяДата, ) КАК Остатки"

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

Вычисление признака просрочки в поле запроса

Текущая дата как параметр удобна в конструкции ВЫБОР — например, пометить просроченные задачи прямо в выборке:

"ВЫБРАТЬ

| Задачи.Ссылка КАК Задача,

| ВЫБОР

| КОГДА Задачи.СрокИсполнения < &ТекущаяДата

| ТОГДА ИСТИНА

| ИНАЧЕ ЛОЖЬ

| КОНЕЦ КАК Просрочена

|ИЗ

| Задача.ЗадачаИсполнителя КАК Задачи"

Альтернатива без запроса: когда параметр не нужен

Если текущая дата нужна не внутри выборки, а для логики обработки результата, запрос вообще не требуется. Например, проверка «документ старше трёх дней» выполняется обычным сравнением в коде: Если Документ.Дата < ТекущаяДатаСеанса() - 3 * 86400 Тогда. Передавать дату в запрос имеет смысл только тогда, когда условие должно выполняться на стороне СУБД — это сокращает объём выбираемых данных.

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

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

Типичные ошибки и как их избежать

Первая и самая частая ошибка — сравнение даты документа с текущей датой через равенство. Дата в 1С всегда содержит время с точностью до секунды, поэтому совпадение практически невозможно. Используйте диапазоны через НачалоДня/КонецДня или функцию запроса НАЧАЛОПЕРИОДА(&ТекущаяДата, ДЕНЬ).

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

Третья ошибка — забыть установить параметр перед выполнением. Запрос упадёт с ошибкой в момент Выполнить(), причём в консоли запросов текст может выглядеть рабочим, потому что там параметр задаётся отдельно. Проверяйте, что УстановитьПараметр вызывается для каждого параметра текста.

Типичные ошибки
01
Сравнение Дата = &ТекущаяДата — условие не сработает из-за времени в составе даты; используйте период дня
02
ТекущаяДата() в клиент-серверной базе — время клиента может отличаться от серверного, отбор даст пропуски или лишние записи
03
Параметр объявлен в тексте, но не установлен — ошибка «Параметр не определён» при выполнении
04
Передача строки вместо даты в УстановитьПараметр — сравнение дат как строк даёт непредсказуемый результат

Проверка результата и ограничения

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

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

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

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

Значение параметра в отладчике
Норма

Дата и время соответствуют текущему моменту на сервере

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

Пустая дата 01.01.0001 или время клиентского компьютера при серверном коде

Отбор документов за сегодня
Норма

В выборку попадают все документы текущего дня независимо от времени

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

Выборка пустая или содержит документы соседних дней

Выполнение запроса
Норма

Запрос выполняется без ошибок

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

Ошибка «Параметр не определён» — параметр не установлен

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

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

Нет, в языке запросов 1С нет функции текущей даты. Значение всегда формируется во встроенном языке через ТекущаяДатаСеанса() и передаётся параметром. Обходных конструкций в самом тексте запроса не существует.

Чем ТекущаяДатаСеанса() отличается от ТекущаяДата()?

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

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

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

Почему условие Дата = &ТекущаяДата не находит документы?

Дата в 1С хранится с точностью до секунды и включает время. Текущая дата содержит текущее время, а дата документа — момент его проведения, поэтому равенство почти никогда не выполняется. Замените сравнение на диапазон дня.

Как передать текущую дату в отчёт на СКД?

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

Меняется ли значение параметра во время выполнения запроса?

Нет. Параметр фиксируется в момент вызова УстановитьПараметр и остаётся постоянным на всё время выполнения. Если нужен новый момент времени, вызовите ТекущаяДатаСеанса() повторно и переустановите параметр перед следующим выполнением.

Итог

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

Текущую дату в запрос 1С передают параметром: получите её через ТекущаяДатаСеанса(), установите через УстановитьПараметр и используйте как &ТекущаяДата. Не сравнивайте даты через равенство из-за времени в составе даты — задавайте диапазон дня. В клиент-серверной базе избегайте ТекущаяДата() в пользу времени сеанса.