При разработке сложных отчетов или механизмов выборки данных в платформе 1С:Предприятие программисты часто сталкиваются с необходимостью фильтрации записей по конкретным временным интервалам. Стандартный оператор ГДЕ позволяет отбирать данные по точным значениям или диапазонам, но иногда требуется более гибкий подход, зависящий от контекста выполнения или динамических условий.
В языке запросов 1С ключевое слово КОГДА (в некоторых контекстах понимаемое как условие времени или специфическая логика выборки периода) играет критическую роль при работе с регистрами накопления и срезами. Ошибки в построении таких условий приводят к тому, что отчет показывает неактуальные остатки или вовсе пустые результаты. Понимание механики работы с временными метками — залог корректной работы любой учетной системы.
Далее мы подробно разберем синтаксические конструкции, позволяющие реализовать логику "когда" в коде запроса, рассмотрим типичные ошибки и предоставим готовые шаблоны для использования в ваших конфигурациях. Особое внимание уделим разнице между физическим временем записи и периодом действия регистра.
Синтаксическая роль условия времени в языке запросов
В строгом синтаксисе языка запросов 1С нет отдельного оператора КОГДА как аналога SQL WHEN внутри конструкции CASE (там используется именно КОГДА как часть ВЫБОР... КОГДА... ТОГДА). Однако в разговорной речи разработчиков фраза "1С в запросе когда" чаще всего относится к двум аспектам: условию отбора по дате (ГДЕ ПериодРегистрации МЕЖДУ) или конструкции условного перехода ВЫБОР.
Рассмотрим первый и наиболее частый сценарий — выборку данных за определенный период. Для регистров накопления и сведений критически важно правильно указать параметр периода. Если вы используете виртуальную таблицу, система сама подставит нужное условие, но при работе с физическими таблицами это ложится на плечи программиста.
Второй сценарий — использование оператора ВЫБОР для преобразования данных на лету. Здесь конструкция КОГДА выступает в роли условия проверки. Например, если нужно пометить документы красным цветом, когда сумма превысила лимит, или изменить статус заказа в зависимости от даты отгрузки. Это мощный инструмент для бизнес-логики прямо внутри запроса, позволяющий избежать лишних проходов по данным в коде 1С.
Используйте конструкцию ВЫБОР... КОГДА... ТОГДА для форматирования данных прямо в запросе, это значительно ускоряет формирование отчетов по сравнению с обработкой в цикле.
Важно различать эти понятия, так как путаница приводит к синтаксическим ошибкам. Компилятор 1С четко разделяет условия фильтрации (ГДЕ) и условные вычисления (ВЫБОР). Правильное понимание контекста, когда применять тот или иной подход, определяет производительность вашего кода.
Работа с периодами в регистрах накопления
Самая распространенная задача, где требуется указать временной интервал, — это получение остатков или оборотов. В 1С для этого предусмотрены виртуальные таблицы, такие как Остатки и Обороты. Ключевой момент здесь — параметр Период, который передается в запрос.
Если вы обращаетесь к физической таблице регистра, вам придется вручную фильтровать записи по полю ПериодРегистрации. Это менее эффективно и чревато ошибками, если не учесть время проведения документов. Всегда старайтесь использовать виртуальные таблицы, так как они оптимизированы платформой для быстрого получения среза на конкретный момент когда был сделан запрос.
При формировании отчета "Оборотно-сальдовая ведомость" или аналогичного, вы должны четко определить границы. Начало периода обычно берется из параметров формы, а конец — либо текущая дата, либо дата конца отчетного периода. Ошибка в одном дне может исказить финансовые показатели.
⚠️ Внимание: При работе с виртуальными таблицами остатков помните, что параметр периода определяет момент времени, на который рассчитываются остатки. Если документ проведен задним числом после этой даты, он не попадет в выборку, даже если физически существует в базе.
Пример правильного обращения к виртуальной таблице выглядит следующим образом. Мы передаем параметр &КонецПериода, и система сама построит оптимальный план выполнения запроса:
ВЫБРАТЬ
РегистрНакопления.ТоварыНаСкладах.Остатки.Номенклатура,
РегистрНакопления.ТоварыНаСкладах.Остатки.КоличествоОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&КонецПериода, ) КАК РегистрНакопления
☑️ Проверка параметров периода
Иногда возникает ситуация, когда нужно получить данные не на конец периода, а на произвольную дату внутри него. Виртуальные таблицы позволяют это сделать гибко, но требуют внимательности к типам данных. Убедитесь, что переменная, передаваемая в запрос, действительно имеет тип Дата, иначе сервер 1С выдаст ошибку преобразования типов.
Конструкция ВЫБОР и логические условия КОГДА
Оператор ВЫБОР в языке запросов 1С является аналогом CASE в стандартном SQL. Он позволяет выполнять ветвление логики непосредственно на уровне базы данных. Синтаксис требует использования ключевого слова КОГДА для перечисления условий.
Эта конструкция незаменима, когда необходимо классифицировать данные без написания дополнительного кода на встроенном языке. Например, вы хотите разделить контрагентов на группы: "Крупные", "Средние" и "Мелкие" в зависимости от суммы задолженности. Вместо того чтобы выбирать все данные и сортировать их в цикле, это можно сделать одним запросом.
Синтаксис выглядит так: ВЫБОР КОГДА Условие1 ТОГДА Значение1 КОГДА Условие2 ТОГДА Значение2 ИНАЧЕ ЗначениеПоУмолчанию КОНЕЦ. Важно соблюдать порядок условий, так как проверка идет последовательно. Как только найдено первое истинное условие КОГДА, остальные игнорируются.
Оптимизация сложных условий ВЫБОР
Если у вас более 10 условий КОГДА в одном запросе, рассмотрите возможность создания временной таблицы со справочником соответствий и сделайте соединение (JOIN) вместо громоздкой конструкции ВЫБОР. Это улучшит читаемость и иногда производительность.
Рассмотрим пример, когда нужно присвоить приоритет заказу в зависимости от его статуса и даты создания:
ВЫБРАТЬ
Заказ.Номер,
ВЫБОР
КОГДА Заказ.Статус = "Срочно" ТОГДА 1
КОГДА Заказ.Дата < &ДатаГраница ТОГДА 2
ИНАЧЕ 3
КОНЕЦ КАК Приоритет
ИЗ
Документ.ЗаказПокупателя КАК Заказ
Использование таких конструкций делает код более декларативным. Вы описываете, какие данные нужны, а не как их получить. Это соответствует лучшей практике программирования в 1С. Однако не стоит злоупотреблять вложенностью, так как сложные деревья ВЫБОР трудно поддерживать.
Обработка временных меток и часовых поясов
Одной из скрытых проблем при работе с условием "когда" является различие во времени. В базе данных 1С время хранится с точностью до секунды (а в новых версиях и выше). При сравнении дат часто возникает ситуация, когда пользователь выбирает период с 01.01.2026 по 31.01.2026, а документы, проведенные 31 января в 23:59:59, не попадают в выборку из-за особенностей округления.
Чтобы избежать потери данных, рекомендуется использовать функцию КонецДня() или добавлять один день к конечной дате при использовании оператора <. Если вы пишете условие вручную для физической таблицы, всегда проверяйте, включает ли ваш диапазон крайние точки.
Также стоит учитывать часовые пояса, если ваша база работает в распределенной среде или через веб-клиент из разных регионов. Сервер 1С хранит время в локальном времени сервера, но клиент может отображать его иначе. Это может привести к путанице, когда документ, созданный "вчера" по времени клиента, оказывается "сегодня" по времени сервера.
| Ситуация | Проблема | Решение |
|---|---|---|
| Выборка за день | Потеря документов после 23:59:00 | Использовать ГДЕ Период < Дата + 1 |
| Сравнение времени | Разница в секундах | Округлять дату функцией НачалоДня() |
| Распределенная база | Смещение часовых поясов | Приводить время к единому стандарту UTC |
| Виртуальные таблицы | Некорректный срез | Передавать точную дату и время в параметр |
Для корректной работы с датами в запросах используйте встроенные функции языка запросов, такие как НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА. Они гарантируют, что вы получите границы интервала именно так, как ожидаете, без ручных вычислений.
Оптимизация запросов с условиями по времени
Условия, содержащие проверку по дате, являются одними из самых ресурсоемких, если не настроены индексы. Платформа 1С автоматически индексирует поля периодов в регистрах, но в обычных документах и справочниках это нужно контролировать. Если ваш запрос выполняется медленно, проверьте, используется ли индексированное поле в условии ГДЕ.
Избегайте применения функций к полям, по которым идет отбор. Например, конструкция ГДЕ ГОД(Документ.Дата) = 2026 заставит сервер перебрать все записи, игнорируя индекс. Правильный вариант — ГДЕ Документ.Дата МЕЖДУ '2026-01-01' И '2026-12-31'. Это фундаментальное правило оптимизации, о котором часто забывают.
⚠️ Внимание: Никогда не используйте вычисляемые поля в условиях отбора по дате, если это возможно. Это отключает использование индексов и может увеличить время выполнения запроса с миллисекунд до минут на больших объемах данных.
Также следует помнить о механизме блокировок. Если вы делаете выборку с целью последующей записи (например, резервирование товара), используйте ключевые слова ДЛЯ ИЗМЕНЕНИЯ. Это заблокирует строки на время транзакции и предотвратит конфликты, когда два пользователя пытаются изменить одни и те же остатки одновременно.
Правильное использование индексов по дате и отказ от функций в условии WHERE (ГДЕ) — главный способ ускорить отчеты в 1С.
Анализ плана выполнения запроса (через Консоль запросов или технологический журнал) покажет, какие именно условия тормозят систему. Часто оказывается, что проблема не в сложности логики КОГДА, а в отсутствии подходящего индекса для поля даты.
Типичные ошибки и способы их устранения
Разработчики часто допускают ошибки при работе с временными интервалами. Самая частая из них — неверное понимание работы оператора МЕЖДУ. В 1С он включает граничные значения. Если вам нужно исключить конечную дату, используйте оператор < с прибавлением единицы к периоду.
Еще одна ошибка — смешивание типов данных. Попытка сравнить поле типа ДатаВремя с параметром типа Дата (без времени) может привести к неожиданному результату. Всегда явно приводите типы или используйте конструктор запроса, который делает это автоматически.
При использовании конструкции ВЫБОР... КОГДА частой ошибкой является отсутствие ветки ИНАЧЕ. Хотя это не всегда критично, отсутствие обработки остальных случаев может привести к тому, что в отчете появятся значения NULL, что сломает дальнейшую логику отображения или математические расчеты.
Для отладки сложных условий рекомендуется выводить текст сформированного запроса в журнал регистрации или консоль. Это позволит увидеть, какие именно значения параметров подставились в момент выполнения и почему условие не сработало так, как планировалось.
Используйте метод ПолучитьТекстЗапроса() объекта QueryBuilder для отладки. Он покажет финальный текст запроса с подставленными параметрами, что упрощает поиск ошибок в условиях КОГДА и ГДЕ.
FAQ: Часто задаваемые вопросы
В чем разница между ГДЕ и КОГДА в запросе 1С?
ГДЕ — это оператор фильтрации строк результата (аналог SQL WHERE). КОГДА — это часть операторов ВЫБОР (аналог SQL CASE) или разговорное обозначение условия по времени. Они выполняют разные функции: одно отбирает строки, другое вычисляет значения внутри строк.
Как выбрать данные за "вчерашний день" в запросе?
Используйте функцию НАЧАЛОДНЯ(ТЕКУЩАЯДАТА() - 1) для начала периода и КОНЕЦДНЯ(ТЕКУЩАЯДАТА() - 1) для конца. В условии ГДЕ лучше использовать МЕЖДУ с этими значениями.
Почему запрос с условием по дате работает медленно?
Скорее всего, к полю даты не применен индекс, либо в условии используется функция (например, ГОД(Дата)), что запрещает использование индекса. Перепишите условие на диапазон дат.
Можно ли использовать несколько условий КОГДА в одном ВЫБОР?
Да, конструкция ВЫБОР поддерживает неограниченное количество ветвей КОГДА... ТОГДА. Проверка осуществляется последовательно сверху вниз до первого совпадения.
Как учесть время в параметре периода регистра?
Если параметр имеет тип Дата (без времени), при передаче в виртуальную таблицу он обычно приводится к началу дня. Для точного среза используйте тип ДатаВремя или явно указывайте время в параметре (например, 23:59:59).