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

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

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

Базовые функции работы с датами в запросе

Язык запросов 1С предоставляет богатый набор встроенных функций для манипулирования временными метками. Наиболее востребованными инструментами являются функции, позволяющие привести дату к началу или концу определенного периода. Это необходимо для группировки данных по месяцам, кварталам или годам без лишней логики в коде обработки.

Функция НАЧАЛОПЕРИОДА принимает дату и возвращает дату начала периода, в котором находится исходное значение. Аналогично работает КОНЕЦПЕРИОДА, возвращая последнюю секунду периода. Платформа поддерживает различные уровни детализации, от секунд до лет, что позволяет гибко настраивать отчетность.

Рассмотрим основные варианты использования этих функций для нормализации временных меток:

  • 📅 НАЧАЛОПЕРИОДА(Дата, НАЧАЛОДНЯ) — обрезает время, оставляя только дату (00:00:00).
  • 📆 НАЧАЛОПЕРИОДА(Дата, НАЧАЛОМЕСЯЦА) — возвращает первое число месяца в 00:00:00.
  • 🗓️ КОНЕЦПЕРИОДА(Дата, КОНЕЦГОДА) — возвращает 31 декабря 23:59:59 текущего года.

Важно понимать, что тип возвращаемого значения всегда остается Дата, но меняется само значение внутри типа. Использование этих функций в конструкции ВЫБОР позволяет динамически определять периоды для каждой строки выборки, что особенно полезно при анализе исторических данных.

⚠️ Внимание: Функции периода работают строго по календарю. Если вы передадите в НАЧАЛОПЕРИОДА дату 31 января, результат будет 1 января, а не 1 февраля. Учитывайте это при расчете следующих периодов.

📊 Какой период вы чаще всего используете в отчетах?
День
Неделя
Месяц
Квартал
Год

Синтаксис отбора по датам в конструкции ГДЕ

Фильтрация записей по временному диапазону — самая частая операция в запросах 1С. Для этого используется секция ГДЕ, где применяются стандартные операторы сравнения. Правильное формирование условий отбора гарантирует использование индексов базы данных и мгновенный поиск нужных документов.

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

Для корректного охвата всего дня рекомендуется использовать следующий подход в параметрах запроса:

ГДЕ

Документ.Дата >= &НачалоПериода

И Документ.Дата < &КонецПериода

Здесь параметр &КонецПериода должен быть установлен на начало следующего дня (или следующего периода), чтобы оператор "меньше" (<) захватил все секунды предыдущего дня включительно. Это стандартный паттерн, обеспечивающий целостность выборки.

💡

Всегда передавайте в параметр конца периода время 00:00:00 следующего дня и используйте строгое неравенство (<). Это избавит от проблем с високосными годами и разным количеством дней в месяцах.

Также стоит отметить возможность использования оператора МЕЖДУ. Он включает обе граничные точки, что требует особой аккуратности при установке времени конца периода. Если вы используете МЕЖДУ, убедитесь, что правая граница установлена на 23:59:59 нужного дня.

Использование виртуальных таблиц и параметров периодов

В конфигурациях на базе 1С:Бухгалтерия или 1С:УТ часто используются регистры накопления, которые имеют специальные виртуальные таблицы для срезов и оборотов. Эти таблицы автоматически принимают параметры периода, что упрощает получение остатков или оборотов на конкретную дату.

При обращении к таким таблицам, например РегистрНакопления.ОстаткиТоваров.Остатки, в запросе указывается параметр КАК. Это позволяет системе самостоятельно сформировать оптимальный план выполнения запроса, учитывая настройки периодичности регистра.

Пример запроса к виртуальной таблице с параметрами:

ВЫБРАТЬ

ОстаткиТоваров.Номенклатура,

ОстаткиТоваров.КоличествоОстаток

ИЗ

РегистрНакопления.ОстаткиТоваров.Остатки(,&КонецПериода) КАК ОстаткиТоваров

ГДЕ

ОстаткиТоваров.КоличествоОстаток <> 0

Здесь параметр &КонецПериода подставляется непосредственно в вызов виртуальной таблицы. Система сама определит, какие физические таблицы читать и как агрегировать данные. Это значительно эффективнее, чем писать ручные выборки с группировками.

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

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

Вычисление дат в выражениях ВЫБОР

Иногда требуется не просто отфильтровать данные, а сгруппировать их по динамически рассчитанным периодам. Конструкция ВЫБОР в языке запросов 1С позволяет выполнять условную логику прямо в списке полей. Это мощный инструмент для аналитики, позволяющий создавать "умные" группировки.

С помощью ВЫБОР можно, например, разделить документы на "просроченные", "текущие" и "будущие" относительно текущей даты сервера. Функция ТЕКУЩАЯДАТА() возвращает момент времени на сервере 1С, что обеспечивает единое время для всех пользователей.

Пример использования условного вычисления периода:

ВЫБРАТЬ

ДокументыРеализации.Ссылка,

ДокументыРеализации.Дата,

ВЫБОР

КОГДА ДокументыРеализации.Дата < НАЧАЛОПЕРИОДА(ТЕКУЩАЯДАТА(), НАЧАЛОМЕСЯЦА)

ТОГДА "Прошлый месяц"

КОГДА ДокументыРеализации.Дата >= НАЧАЛОПЕРИОДА(ТЕКУЩАЯДАТА(), НАЧАЛОМЕСЯЦА)

ТОГДА "Текущий месяц"

КОНЕЦ КАК ПериодГруппировки

ИЗ

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

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

⚠️ Внимание: Функция ТЕКУЩАЯДАТА() в запросе вычисляется один раз для всего запроса, а не для каждой строки. Однако в сложных вложенных запросах поведение может отличаться, поэтому проверяйте результаты тестированием.

Работа с временем и точностью до секунды

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

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

Для получения текущей даты и времени в запросе используется функция ТЕКУЩАЯДАТА(). Если нужно обрезать время до минут или секунд, используйте соответствующие параметры в функциях периода:

  • ⏱️ НАЧАЛОПЕРИОДА(Дата, НАЧАЛОМИНУТЫ) — округляет до начала минуты.
  • КОНЕЦПЕРИОДА(Дата, КОНЕЦСЕКУНДЫ) — возвращает дату с тем же значением секунд, но обнуляет миллисекунды (если они есть в источнике).

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

Особенности хранения дат в SQL

В файловой базе 1С даты хранятся в собственном формате. В клиент-серверном варианте (MS SQL, PostgreSQL) они преобразуются в нативный тип данных СУБД. Это может приводить к микроскопическим различиям в миллисекундах при прямых SQL-запросах, но внутри языка запросов 1С эти различия нивелируются.

Оптимизация производительности при отборе по датам

Эффективность запросов напрямую зависит от того, как сформулированы условия отбора по датам. База данных использует индексы для ускорения поиска, но только если условие написано корректно. Применение функций к полям таблицы в условии ГДЕ часто приводит к полному сканированию таблицы (Full Table Scan), что недопустимо на больших объемах.

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

Правильный подход — вычислять границы периода в параметрах запроса перед его выполнением:

// Неправильно (медленно)

ГДЕ НАЧАЛОПЕРИОДА(Т.Дата, НАЧАЛОДНЯ) = &НужнаяДата

// Правильно (быстро)

ГДЕ Т.Дата >= &НачалоДня И Т.Дата < &КонецДня

В варианте "Правильно" значения &НачалоДня и &КонецДня вычисляются в коде 1С один раз, а в запрос передаются готовые константы. Это позволяет СУБД использовать индекс диапазона (Range Scan) и мгновенно находить нужные записи.

⚠️ Внимание: Никогда не применяйте функции преобразования дат к полям таблиц в секции ГДЕ, если это возможно. Всегда вычисляйте константы в коде перед запуском запроса для использования индексов.

☑️ Чек-лист оптимизации дат

Выполнено: 0 / 5

Часто задаваемые вопросы (FAQ)

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

Используйте комбинацию функций НАЧАЛОПЕРИОДА(ТЕКУЩАЯДАТА(), НАЧАЛОДНЯ). Это вернет дату сегодня с временем 00:00:00, что удобно для сравнения с датами документов, у которых время не важно.

Почему запрос не находит документы за 31 декабря, если я указал конец периода 31.12?

Скорее всего, вы используете условие "Меньше или равно" (<<=) и передали дату 31.12 без времени (00:00:00). Документы, созданные днем 31 декабря, имеют время больше 00:00:00 и не попадают в выборку. Используйте условие "Меньше" (<) с датой 01.01 следующего года.

Можно ли в запросе 1С добавить к дате один месяц?

Да, для этого существует функция ДОБАВИТЬКДАТЕ(Дата, МЕСЯЦ, 1). Она корректно учитывает переходы через год и разное количество дней в месяцах. Аналогично можно добавлять годы, кварталы или минуты.

В чем разница между НАЧАЛОПЕРИОДА и ОКРУГЛИТЬДАТУ?

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

Как работать с датами в файловом варианте 1С?

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