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

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

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

Синтаксис и базовые принципы работы КОГДА

Оператор КОГДА позволяет возвращать различные значения в зависимости от выполнения определенных условий. Это аналог оператора Switch или тернарного оператора в императивных языках, но реализованный на уровне СУБД. Базовая структура выглядит как последовательность проверок: если условие истинно, возвращается соответствующее значение, иначе проверка переходит к следующему пункту.

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

⚠️ Внимание: Если вы не укажете ветку ИНАЧЕ, а ни одно из условий не выполнится, в результирующей таблице будет возвращено значение NULL (Пустая ссылка). Это часто приводит к ошибкам при дальнейшей обработке данных или выводе отчетов, поэтому всегда явно определяйте значение по умолчанию.

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

ВЫБРАТЬ

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

КОГДА Номенклатура.ВидНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ВидыНоменклатуры.Услуга) ТОГДА "Услуга"

ИНАЧЕ "Товар"

КОНЕЦ КАК ТипОбъекта

ИЗ

Справочник.Номенклатура КАК Номенклатура

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

💡

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

Работа с датами: начало и конец периодов

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

Представьте ситуацию, когда вам нужно определить дату начала отчетного периода, но с условием: если документ датирован первым числом месяца, то период начинается с этого числа, а если нет — с первого числа предыдущего месяца. Реализовать такую логику можно одной строкой кода внутри выборки.

Функция Описание Пример результата для 15.05.2026
НАЧАЛОПЕРИОДА(Дата, МЕСЯЦ) Возвращает начало месяца 01.05.2026 0:00:00
КОНЕЦПЕРИОДА(Дата, МЕСЯЦ) Возвращает конец месяца 31.05.2026 23:59:59
НАЧАЛОПЕРИОДА(Дата, КВАРТАЛ) Возвращает начало квартала 01.04.2026 0:00:00
КОНЕЦПЕРИОДА(Дата, ГОД) Возвращает конец года 31.12.2026 23:59:59

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

Часто возникает необходимость сравнить дату документа с текущей датой (&ТекущаяДата). Если документ из будущего, мы можем помечать его специальным флагом «Плановый», а если из прошлого — «Фактический». Это делается без дополнительных циклов обработки.

ВЫБРАТЬ

Документ.Дата,

КОГДА Документ.Дата > &ТекущаяДата ТОГДА "Плановый"

ИНАЧЕ "Фактический"

КОНЕЦ КАК СтатусВремени

ИЗ

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

📊 Как вы чаще определяете границы периода в отчетах?
В коде 1С перед запросом
Функциями в теле запроса
Через параметры СКД
Вручную вводом значений

Оптимизация производительности при использовании КОГДА

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

Главное правило оптимизации: ставьте самые вероятные условия в начало списка. Если 90% ваших документов имеют статус «Проведен», то проверка на этот статус должна идти первой. Это позволит СУБД быстрее отсеивать или подтверждать условия для большинства записей.

⚠️ Внимание: Избегайте вызова тяжелых пользовательских функций или обращений к другим таблицам внутри условий оператора КОГДА. Это может превратить быстрый запрос в длительный процесс, так как условие будет вычисляться для каждой строки результата.

Также стоит учитывать, что использование КОГДА для формирования полей, по которым идет группировка или сортировка, может быть менее эффективным, чем использование временных таблиц. Если логика выбора значения очень сложная, иногда выгоднее сделать два простых запроса с объединением ОБЪЕДИНИТЬ ВСЕ, чем один сложный с множеством вложенных условий.

Для анализа эффективности используйте Консоль запросов и смотрите на план выполнения. Если вы видите операцию Table Scan (полное сканирование таблицы) там, где ожидается Index Seek, попробуйте переписать условия или вынести часть логики за пределы запроса.

💡

Порядок условий в операторе КОГДА влияет на читаемость кода, но современные СУБД (MS SQL, PostgreSQL) обычно сами оптимизируют порядок проверки. Однако для совместимости и предсказуемости ставьте наиболее частые случаи первыми.

Вложенные конструкции и сложная логика

Оператор КОГДА поддерживает вложенность. Вы можете использовать один оператор КОГДА внутри ветки ТОГДА или ИНАЧЕ другого оператора. Это позволяет реализовывать многоуровневую логику классификации данных, аналогичную вложенным операторам If в коде.

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

Рассмотрим пример вложенной логики для расчета коэффициента премии в зависимости от отдела и выполнения плана. Сначала проверяем отдел, а внутри — процент выполнения:

ВЫБРАТЬ

Сотрудник.ФИО,

КОГДА Сотрудник.Подразделение = &ОтделПродаж ТОГДА

(КОГДА Сотрудник.ВыполнениеПлана > 100 ТОГДА 1.5 ИНАЧЕ 1.0 КОНЕЦ)

ИНАЧЕ

(КОГДА Сотрудник.ВыполнениеПлана > 120 ТОГДА 1.2 ИНАЧЕ 1.0 КОНЕЦ)

КОНЕЦ КАК КоэффициентПремии

ИЗ

Справочник.Сотрудники КАК Сотрудник

Такой подход позволяет избежать дублирования кода и хранить всю бизнес-логику расчета в одном месте — в запросе формирования отчета. Это особенно удобно при использовании Системы Компоновки Данных, где запрос является основным источником метаданных для схемы.

Максимальная глубина вложенности

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

Использование в Системе Компоновки Данных (СКД)

В СКД оператор КОГДА играет ключевую роль при создании вычисляемых полей. Часто бывает необходимо вывести в отчете человеко-понятное описание вместо кода справочника или перечисления. Например, вместо значения перечисления СтатусЗаказа.ВРаботе вывести текст «В работе».

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

  • 📊 Группировка: Можно группировать записи по результату вычисления КОГДА, объединяя разные значения справочников в одну логическую группу (например, «Транспортные расходы» = Бензин + Ремонт + Амортизация).
  • 🎨 Условное оформление: Результат оператора часто используют как условие для изменения цвета ячейки или шрифта. Например, если расчетное поле «Отклонение» меньше нуля, красить ячейку в красный цвет.
  • 🔍 Отборы: Поля, рассчитанные через КОГДА, можно использовать в отборах отчета, позволяя пользователю фильтровать данные по сформированным категориям.

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

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

☑️ Проверка отчета с КОГДА

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

Частые ошибки и способы их решения

Самая распространенная ошибка — несоответствие типов данных в ветках ТОГДА и ИНАЧЕ. Язык запросов 1С строго типизирован. Если в одной ветке вы возвращаете Число, а в другой Строку, компилятор запросов выдаст ошибку «Неверный тип аргумента» или приведение типов может сработать не так, как вы ожидаете.

Всегда приводите результаты к единому типу. Если нужно вернуть число или пустое значение, используйте NULL (что совместимо с любым типом) или явно преобразуйте типы. Например, если одна ветка возвращает 0, а другая NULL, итоговый тип поля будет Числовым, что корректно.

Еще одна ошибка — попытка использовать оператор КОГДА для изменения данных. Запрос в 1С (конструкция ВЫБРАТЬ) только читает данные. Он не может обновлять записи в базе. Для изменения данных нужно использовать механизмы объектов или специальные запросы изменения, но там синтаксис КОГДА не применяется в том же виде.

Также разработчики часто забывают про приоритет операций. Если вы смешиваете КОГДА с арифметическими операциями, обязательно используйте скобки. Без скобок порядок вычислений может быть нарушен, и результат окажется неверным.

/ Правильно /

(КОГДА А > 0 ТОГДА А ИНАЧЕ 0 КОНЕЦ) + Б

/ Ошибочно (может вызвать ошибку синтаксиса или логики) /

КОГДА А > 0 ТОГДА А ИНАЧЕ 0 КОНЕЦ + Б

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

💡

При отладке запросов с КОГДА добавьте в выборку исходные поля, от которых зависит условие. Так вы сразу увидите в консоли запросов, почему сработала та или иная ветка, не запуская запрос многократно с разными параметрами.

Можно ли использовать оператор КОГДА в условиях соединения (ЛЕВОЕ СОЕДИНЕНИЕ)?

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

В чем разница между КОГДА в запросе и Если в коде 1С?

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

Как вернуть NULL в операторе КОГДА?

Для возврата пустого значения используйте ключевое слово NULL (или ЕСТЬNULL в некоторых контекстах, но в ветках ТОГДА чаще пишут просто NULL). Это универсальное значение, которое принимает любой тип поля результата.

Можно ли сравнивать даты с временем в операторе КОГДА?

Да, тип Дата в 1С включает в себя время. Сравнение происходит точно до секунды. Если вам нужно сравнить только даты без учета времени, используйте функцию НАЧАЛОДНЯ(Дата) в условии сравнения для обеих частей.

Влияет ли КОГДА на использование индексов?

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