Работа с временными данными в системе 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. Но если в условии использовать строгое меньше (<), эта запись может выпасть.
Еще одна проблема связана с часовыми поясами. В клиент-серверном варианте работы время может конвертироваться между часовым поясом клиента и сервера. Оператор КОГДА работает с датой в контексте сервера, поэтому при передаче параметров с клиентского места необходимо учитывать возможный сдвиг времени.
Также стоит помнить о точности хранения дат. В некоторых конфигурациях или старых версиях платформы время могло округляться до минут. Современные версии хранят время с точностью до секунды или миллисекунды, что требует более аккуратного сравнения.
☑️ Проверка корректности запроса по дате
Примеры использования в коде 1С
Рассмотрим практический пример формирования запроса для отчета по продажам за выбранный период. В данном случае мы используем параметры для передачи границ диапазона, что обеспечивает гибкость и переиспользование кода.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Продажи.Ссылка КАК Ссылка,
| Продажи.Дата КАК Дата,
| Продажи.Сумма КАК Сумма
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Продажи
|ГДЕ
| Продажи.Дата КОГДА МЕЖДУ &Начало И &Конец";
Запрос.УстановитьПараметр("Начало", НачалоПериода);
Запрос.УстановитьПараметр("Конец", КонецПериода);
Результат = Запрос.Выполнить();
В этом примере оператор КОГДА МЕЖДУ гарантирует, что будут выбраны все документы, дата которых попадает в указанный интервал включительно. Переменные Начало и Конец должны быть рассчитаны заранее в коде с учетом бизнес-требований отчета.
Если требуется выбрать данные за конкретный день, введенный пользователем в форму, достаточно передать эту дату в параметр. Платформа сама раскроет её в диапазон от 00:00:00 до 23:59:59 благодаря использованию оператора КОГДА.
Как обработать пустой параметр даты в запросе?
Если параметр даты может быть не заполнен, используйте конструкцию ИЛИ &Параметр ЕСТЬ NULL в условии, либо формируйте текст запроса динамически в зависимости от наличия значения.
Можно ли использовать КОГДА для регистров сведений?
Да, оператор применим к любым полям типа Дата, включая измерения и ресурсы регистров сведений, накопления и бухгалтерии.
Влияет ли версия платформы на работу оператора?
Базовая логика оператора стабильна, но точность хранения времени и работа с часовыми поясами могут отличаться в версиях 7.7, 8.1, 8.2 и 8.3. Рекомендуется тестировать на целевой платформе.