Работа с временными данными в системе 1С:Предприятие является одной из самых частых задач для разработчика. При построении отчетов, обработке документов или анализе движения средств необходимо уметь точно отбирать записи по периоду. Для решения этой задачи в языке запросов платформы предусмотрен специализированный оператор КОГДА, который позволяет фильтровать данные на основе значений полей типа Дата.

В отличие от стандартных операторов сравнения, таких как = или <>, конструкция КОГДА обладает уникальной логикой работы с временными интервалами. Она автоматически учитывает точность даты, указанную в условии, и корректно обрабатывает ситуации, когда время не задано явно. Понимание механики этого оператора критически важно для написания производительных и корректных запросов, особенно при работе с большими объемами исторических данных.

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

Синтаксис и базовая логика работы

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

Ключевая особенность заключается в том, как платформа интерпретирует отсутствие времени в заданном значении. Если вы указываете дату без времени, например, ДАТАВРЕМЯ(2023, 10, 5), система автоматически подставляет начало суток (00:00:00). Однако логика оператора КОГДА подразумевает включение всего дня, если не указано иное. Это часто становится источником путаницы у начинающих разработчиков, ожидающих строгого равенства.

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

Условие в запросе Интерпретация диапазоном Включает время 23:59:59
Дата КОГДА &20231005 05.10.2023 00:00:00 - 05.10.2023 23:59:59 Да
Дата = &20231005 Только 05.10.2023 00:00:00 Нет
Дата >= &20231005 От 05.10.2023 00:00:00 до бесконечности Да

⚠️ Внимание: При использовании оператора КОГДА с параметром, передаваемым из кода, убедитесь, что тип параметра строго соответствует типу Дата. Передача строкового представления даты может привести к ошибке выполнения запроса или некорректному сравнению.

💡

Используйте литерал даты в формате &ГГГГММДД для жесткой фиксации значения в тексте запроса, это упрощает отладку и чтение кода.

Работа с периодами и интервалами

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

Если требуется выбрать документы, проведенные в течение определенного месяца, можно использовать конструкцию Дата КОГДА МЕЖДУ НачалоПериода И КонецПериода. В случае, если время не указано, система может интерпретировать конец периода как начало следующих суток, что требует внимательной проверки логики.

Для работы со скользящими периодами, такими как "последние 7 дней" или "текущий квартал", удобно использовать встроенные функции даты в сочетании с параметрами запроса. Это позволяет делать запросы универсальными и не привязанными к жестким календарным датам.

  • 📅 Использование НАЧАЛОПЕРИОДА позволяет точно задать точку отсчета для выборки данных.
  • ⏳ Функция КОНЕЦПЕРИОДА автоматически рассчитывает последнюю миллисекунду указанного интервала.
  • 🔄 Динамические параметры в коде позволяют пользователю менять период отчета без изменения текста запроса.
📊 Какой способ задания периода вы используете чаще?
Жесткие даты в коде
Параметры формы
Функции начала/конца периода
Срез последних регистров

Сравнение с оператором равенства

Многие разработчики задаются вопросом: в чем принципиальная разница между Поле = Дата и Поле КОГДА Дата? Различие фундаментально. Оператор равенства требует полного совпадения значения, включая время с точностью до секунды (или миллисекунды в зависимости от версии платформы).

Если в базе данных документ проведен в 14:30, а вы ищете запись с условием Дата = 20.10.2023 (что равно 20.10.2023 00:00:00), запрос ничего не найдет. В то же время условие Дата КОГДА 20.10.2023 успешно выберет этот документ, так как оно охватывает весь временной диапазон суток.

Использование знака равенства для дат оправдано только в редких случаях, когда требуется найти запись с конкретным временем создания, например, при отладке или поиске дублей, созданных в одну и ту же миллисекунду. В бизнес-логике практически всегда требуется работа с интервалами, поэтому КОГДА является предпочтительным выбором.

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

Технические детали сравнения дат

Внутренне даты в 1С хранятся как количество секунд с начала эры. Оператор КОГДА выполняет преобразование диапазона в числовые границы перед передачей условия в СУБД.

Производительность и использование индексов

Эффективность выполнения запроса напрямую зависит от того, сможет ли СУБД использовать индекс по полю даты. Оператор КОГДА оптимизирован платформой для работы с индексами. При правильном написании условия запрос преобразуется в диапазонное условие BETWEEN или пару условий >= AND <= на языке SQL.

Однако существуют ситуации, когда индекс не используется. Это происходит, если к полю даты применяются функции непосредственно в условии выбора. Например, конструкция ГОД(Дата) = 2023 вынудит сервер просканировать всю таблицу, так как функция применяется к каждой строке. Правильный подход — вычислять границы периода в параметрах и передавать их в запрос.

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

💡

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

Типичные ошибки и способы их устранения

При работе с временными данными разработчики часто совершают ряд типичных ошибок, которые приводят к логическим несоответствиям в отчетах. Одна из самых распространенных — неверный расчет верхней границы периода. Если использовать КонецПериода(Дата, "Месяц"), мы получим дату 31-го числа 23:59:59. Но если в условии использовать строгое меньше (<), эта запись может выпасть.

Еще одна проблема связана с часовыми поясами. В клиент-серверном варианте работы время может конвертироваться между часовым поясом клиента и сервера. Оператор КОГДА работает с датой в контексте сервера, поэтому при передаче параметров с клиентского места необходимо учитывать возможный сдвиг времени.

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

☑️ Проверка корректности запроса по дате

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

Примеры использования в коде 1С

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

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

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

"ВЫБРАТЬ

| Продажи.Ссылка КАК Ссылка,

| Продажи.Дата КАК Дата,

| Продажи.Сумма КАК Сумма

|ИЗ

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

|ГДЕ

| Продажи.Дата КОГДА МЕЖДУ &Начало И &Конец";

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

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

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

В этом примере оператор КОГДА МЕЖДУ гарантирует, что будут выбраны все документы, дата которых попадает в указанный интервал включительно. Переменные Начало и Конец должны быть рассчитаны заранее в коде с учетом бизнес-требований отчета.

Если требуется выбрать данные за конкретный день, введенный пользователем в форму, достаточно передать эту дату в параметр. Платформа сама раскроет её в диапазон от 00:00:00 до 23:59:59 благодаря использованию оператора КОГДА.

Как обработать пустой параметр даты в запросе?

Если параметр даты может быть не заполнен, используйте конструкцию ИЛИ &Параметр ЕСТЬ NULL в условии, либо формируйте текст запроса динамически в зависимости от наличия значения.

Можно ли использовать КОГДА для регистров сведений?

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

Влияет ли версия платформы на работу оператора?

Базовая логика оператора стабильна, но точность хранения времени и работа с часовыми поясами могут отличаться в версиях 7.7, 8.1, 8.2 и 8.3. Рекомендуется тестировать на целевой платформе.