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

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

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

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

Рассмотрим простейший пример выборки остатков товаров на складе. В данном случае мы обращаемся к виртуальной таблице, где условие КОГДА определяет срез остатков. Система автоматически построит запрос к физической таблице регистра, выбрав записи, актуальные на указанную дату.

ВЫБРАТЬ

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

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

ИЗ

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

ГДЕ

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

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

💡

При использовании виртуальных таблиц остатков всегда передавайте дату среза вторым параметром в скобках после имени таблицы. Это гарантирует использование оптимизированного механизма выборки 1С.

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

Работа с регистрами накопления и срезами

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

Использование КОГДА (или его аналогов в параметрах виртуальных таблиц) позволяет избежать ручного суммирования всех приходных и расходных документов за всю историю. Платформа 1С использует специальные таблицы итогов (totals), которые ускоряют получение срезов в сотни раз по сравнению с полным перебором движений.

  • 📅 Выборка остатков на конкретную дату требует указания точного момента времени с учетом времени суток.
  • ⚖️ Для оборотных регистров важно различать срезы остатков и срезы оборотов за период.
  • 🚀 Использование виртуальных таблиц предпочтительнее ручных расчетов сумм в коде запроса.

Особое внимание следует уделить типу даты. В 1С дата включает в себя и время. Если вы запрашиваете остатки на конец дня, необходимо указывать время 23:59:59 или использовать специальную функцию КонецДня(). Ошибка в указании времени может привести к тому, что документы, проведенные в последние минуты дня, не попадут в выборку.

📊 С каким типом регистров вы работаете чаще всего?
Регистры накопления
Регистры сведений
Регистры бухгалтерии
Регистры расчета

⚠️ Внимание: При выборке данных из регистров накопления всегда проверяйте тип периода регистра (Неопределенный, День, Месяц, Год, Квартал). От этого зависит granularity таблиц итогов и точность среза без дополнительного пересчета.

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

Сравнение КОГДА и ЗНАЧЕНИЕ в условиях выборки

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

Оператор ЗНАЧЕНИЕ используется для приведения строкового представления к конкретному типу данных 1С внутри текста запроса. Это необходимо, когда в условие ГДЕ передается константа, например, вид операции или конкретный элемент справочника. В то время как КОГДА (логически) отвечает за временную ось, ЗНАЧЕНИЕ отвечает за типизацию констант.

ВЫБРАТЬ

Движения.Период,

Движения.Сумма

ИЗ

РегистрНакопления.ФинансовыйРезультат.Обороты(

&НачПериода,

&КонПериода,

,

"ВидОперации = ЗНАЧЕНИЕ(Перечисление.ВидыФинансовыхОпераций.Продажа)"

) КАК Движения

В данном примере мы видим комбинацию подходов. Период задается параметрами (аналог "когда"), а фильтрация по виду операции требует явного указания типа через ЗНАЧЕНИЕ. Неправильное использование этих конструкций приведет к ошибке выполнения запроса или неверным данным.

Почему нельзя просто написать строку в запросе?

Текст запроса компилируется в дерево запросов. Без указания типа (ЗНАЧЕНИЕ) система не поймет, является ли строка 'Продажа' именем поля, строковой константой или ссылкой на объект метаданных.

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

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

Производительность запросов с временными условиями напрямую зависит от структуры индексов в базе данных и настроек регистров. Неправильное использование условий выбора может привести к полному сканированию таблиц (table scan), что критично для баз с миллионами записей.

Ключевым фактором оптимизации является использование полей, входящих в ведущий набор измерений регистра, в условиях ГДЕ. Если условие по дате (логическое "КОГДА") стоит первым, а фильтрация по конкретному складу или контрагенту отсутствует, СУБД может выбрать неоптимальный план.

Ситуация Рекомендация Влияние на скорость
Выборка за большой период без фильтров Использовать агрегированные таблицы итогов Высокое ускорение
Частая выборка по конкретному элементу Добавить измерение в ведущий набор Среднее ускорение
Срез остатков на текущую дату Использовать виртуальную таблицу Остатки Максимальная скорость

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

💡

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

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

Обработка ошибок и исключительных ситуаций

При работе с запросами, содержащими временные условия, возможны различные ошибки выполнения. Наиболее частая проблема — несоответствие типов данных в параметрах даты. Передача строки вместо даты или значения NULL в обязательный параметр периода вызовет исключение.

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

⚠️ Внимание: При передаче параметров даты из формы в запрос убедитесь, что поле даты заполнено. Пустая дата часто интерпретируется как 0001.01.01, что может выбрать все данные за всю историю существования базы.

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

Практические примеры в коде 1С

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

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

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

"ВЫБРАТЬ

| ОборотыДт.СчетДт,

| СУММА(ОборотыДт.Сумма) КАК СуммаОборотаДт

|ИЗ

| РегистрБухгалтерии.Хозрасчетный.ОборотыДт(

| &НачалоПериода,

| &КонецПериода,

| ,

| ,

| ) КАК ОборотыДт

|

|СГРУППИРОВАТЬ ПО

| ОборотыДт.СчетДт";

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

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

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

В этом коде параметры &НачалоПериода и &КонецПериода реализуют логику выбора данных "когда". Виртуальная таблица ОборотыДт автоматически фильтрует движения по регистру бухгалтерии. Это стандартный паттерн для большинства отчетов в 1С:Бухгалтерия и 1С:ERP.

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

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

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

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

Можно ли использовать слово КОГДА напрямую в тексте запроса 1С?

В явном виде ключевое слово КОГДА в синтаксисе запросов 1С (в отличие от SQL) используется редко. Чаще его функционал реализуется через параметры виртуальных таблиц регистров (например, Остатки(&Параметр1, &Дата)) или через условие ГДЕ Период.Между(&Нач, &Кон). Прямой синтаксис WHERE ... WHEN не поддерживается в языке запросов 1С в том виде, как в стандартном SQL.

Как получить остатки на конкретную дату, если регистр не имеет итогов?

Если регистр накопления не имеет установлена флага "Итоги", выборка среза остатков будет производиться путем суммирования всех движений с начала работы базы до указанной даты. Это значительно медленнее. Рекомендуется включать итоги для регистров, по которым часто формируются отчеты.

В чем разница между Виртуальной таблицей и физическим запросом?

Виртуальная таблица — это специальный объект метаданных, который при выполнении запроса трансформируется в оптимальный SQL-код с учетом особенностей регистра (наличие итогов, видов движений). Физический запрос к таблице регистра требует ручного написания логики выборки и группировки, что сложнее и менее производительно.

Почему запрос с датой возвращает пустой результат?

Наиболее вероятная причина — несовпадение времени. Если в базе документы проведены с временем 10:00, а вы запрашиваете срез на 00:00 того же дня, документы не попадут в выборку. Всегда используйте КонецДня() или указывайте время явно.