Конструкция Выбор-Когда (или Switch-Case в других языках программирования) — один из ключевых элементов управления потоком выполнения в 1С:Предприятие 8.3. Она позволяет заменить громоздкие цепочки условий Если-Тогда на компактный и читаемый код, особенно когда требуется проверить значение одной переменной на соответствие нескольким вариантам. Однако, несмотря на кажущуюся простоту, у этой конструкции есть нюансы, которые могут приводить к ошибкам или неоптимальной работе кода.

Многие разработчики недооценивают гибкость Выбор-Когда, используя её только для примитивных проверок. Между тем, с её помощью можно организовывать сложную логику с вложенными условиями, работать с диапазонами значений, а также оптимизировать производительность за счёт сокращения количества проверок. В этой статье мы разберём синтаксис конструкции, покажем реальные примеры её применения в типовых задачах (от обработки документов до работы с справочниками), а также проанализируем типичные ошибки и способы их избежать.

Особое внимание уделим сравнению Выбор-Когда с альтернативными подходами — почему в некоторых случаях лучше использовать Если-Тогда-Иначе, а где без Выбор-Когда не обойтись. Также рассмотрим малоизвестные возможности, такие как использование конструкции с объектами (например, СправочникСсылка) и работа с коллекциями.

📊 Как часто вы используете конструкцию Выбор-Когда в 1С?
Часто, почти в каждом модуле
Иногда, когда много условий
Рядом, предпочитаю Если-Тогда
Никогда не использовал

Синтаксис конструкции Выбор-Когда: базовые правила

Конструкция Выбор-Когда в 1С 8.3 имеет следующий базовый синтаксис:

Выбор

Когда <Условие1> Тогда

// Действия 1

Когда <Условие2> Тогда

// Действия 2

...

Иначе

// Действия по умолчанию

КонецВыбора;

Ключевые особенности синтаксиса:

  • 📌 Каждое условие Когда должно заканчиваться словом Тогда (в отличие от некоторых языков, где используется двоеточие или фигурные скобки).
  • 📌 Блок Иначе не обязателен — если ни одно из условий не выполнено, выполнение кода просто продолжится после КонецВыбора.
  • 📌 Внутри каждого блока Тогда может быть произвольное количество операторов, но они не требуют оборачивания в НачатьПопытку или другие конструкции.
  • 📌 Условия проверяются последовательно, и выполнение прерывается после первого совпадения (в отличие от Если-Тогда, где можно использовать ИначеЕсли для продолжения проверок).

Важно понимать, что Выбор-Когда работает с одним выражением, которое сравнивается с разными вариантами. Например, если вам нужно проверить диапазон значений (например, Если Значение > 10 И Значение < 20), то Выбор-Когда для этого не подходит — здесь уместнее Если-Тогда.

Пример простейшего использования:

ДеньНедели = ДеньНедели(ТекущаяДата());

Выбор

Когда ДеньНедели = 1 Тогда

Сообщить("Понедельник - день тяжёлый");

Когда ДеньНедели = 5 Тогда

Сообщить("Пятница - почти выходной!");

Иначе

Сообщить("Обычный рабочий день");

КонецВыбора;

💡

Если в блоке Когда нужно проверить несколько условий (например, Когда Значение = 10 Или Значение = 20), используйте логические операторы. Однако такой подход снижает читаемость — в этом случае лучше рассмотреть альтернативные конструкции.

Когда использовать Выбор-Когда, а когда Если-Тогда?

Многие разработчики сталкиваются с дилеммой: что выбрать — Выбор-Когда или цепочку Если-Тогда-ИначеЕсли? Ответ зависит от конкретной задачи. Вот ключевые критерии:

Критерий Выбор-Когда Если-Тогда-ИначеЕсли
Количество проверяемых условий Много (3+) Мало (1-2)
Тип проверки Сравнение одного выражения с разными значениями Разные условия (например, Если ТипДок = "Заказ" И Сумма > 1000)
Читаемость кода Выше при большом количестве вариантов Выше при сложных составных условиях
Производительность Быстрее (проверки оптимизированы) Медленнее при большом количестве условий
Вложенные условия Не поддерживаются напрямую Поддерживаются (можно использовать вложенные Если)

Пример, где Выбор-Когда предпочтительнее:

Выбор

Когда ТипОперации = Тип("Документ.ПоступлениеТоваров") Тогда

// Логика для поступления

Когда ТипОперации = Тип("Документ.РеализацияТоваров") Тогда

// Логика для реализации

Когда ТипОперации = Тип("Документ.ВозвратОтПокупателя") Тогда

// Логика для возврата

КонецВыбора;

А здесь лучше Если-Тогда:

Если Номенклатура.ЭтоГруппа() И Номенклатура.ПометкаУдаления Тогда

Сообщить("Нельзя работать с помеченной группой!");

ИначеЕсли Номенклатура.Архивный Тогда

Сообщить("Номенклатура архивная!");

Иначе

// Основная логика

КонецЕсли;

💡

Если вам нужно проверить одно и то же выражение на равенство разным значениям — используйте Выбор-Когда. Если условия разные и сложные — Если-Тогда будет уместнее.

Практические примеры использования Выбор-Когда

Рассмотрим реальные сценарии, где Выбор-Когда помогает сделать код лаконичнее и понятнее.

1. Обработка статусов документов

Типовая задача — выполнение разных действий в зависимости от статуса документа (например, "Согласован", "Отклонён", "Выполнен"):

Выбор

Когда СтатусДокумента = Перечисление.СтатусыДокументов.Согласован Тогда

РазрешитьПроводить();

ЗаписатьДокумент();

Когда СтатусДокумента = Перечисление.СтатусыДокументов.Отклонен Тогда

Сообщить("Документ отклонён! Причина: " + ПричинаОтклонения);

Когда СтатусДокумента = Перечисление.СтатусыДокументов.НаУтверждении Тогда

ОтправитьНаУтверждение(Руководитель);

КонецВыбора;

2. Работа с типами данных

Полезно при динамической обработке разных типов (например, в универсальных функциях):

Выбор

Когда ТипЗнч(Значение) = Тип("Строка") Тогда

Результат = СтрДлина(Значение);

Когда ТипЗнч(Значение) = Тип("Число") Тогда

Результат = Окр(Значение, 2);

Когда ТипЗнч(Значение) = Тип("Дата") Тогда

Результат = Формат(Значение, "ДФ=dd.MM.yyyy");

Иначе

Результат = Неопределено;

КонецВыбора;

3. Обработка кодов ошибок

При работе с API или внешними системами часто нужно реагировать на разные коды ответов:

КодОтвета = ПолучитьКодОтветаИзAPI();

Выбор

Когда КодОтвета = 200 Тогда

Сообщить("Успех!");

ОбработатьДанные(Ответ);

Когда КодОтвета = 401 Тогда

ВызватьИсключение("Не авторизован! Токен: " + ТокенДоступа);

Когда КодОтвета = 404 Тогда

Сообщить("Ресурс не найден");

Иначе

ЗаписатьВЛогОшибку(КодОтвета);

КонецВыбора;

4. Локализация сообщений

Если ваша конфигурация поддерживает несколько языков, Выбор-Когда удобен для выбора переводов:

Выбор

Когда ТекущийЯзык = "ru" Тогда

Сообщение = "Документ сохранён";

Когда ТекущийЯзык = "en" Тогда

Сообщение = "Document saved";

Когда ТекущийЯзык = "kk" Тогда

Сообщение = "Құжат сақталды";

КонецВыбора;

Убедитесь, что проверяется одно выражение|Проверьте, что условия не пересекаются|Добавьте блок Иначе для обработки неожиданных значений|Рассмотрите альтернативы, если условий больше 10-->

Типичные ошибки и как их избежать

Даже опытные разработчики иногда допускают ошибки при работе с Выбор-Когда. Вот самые распространённые из них:

1. Отсутствие блока Иначе

Если не обработать вариант, когда ни одно из условий не выполнено, это может привести к логическим ошибкам. Например:

Выбор

Когда Цвет = "Красный" Тогда

Цена = Цена * 1.1;

Когда Цвет = "Синий" Тогда

Цена = Цена * 0.9;

// Нет блока Иначе!

КонецВыбора;

В этом случае, если Цвет будет "Зелёный", переменная Цена останется без изменений, что может быть неожиданным поведением.

2. Пересекающиеся условия

Если условия в блоках Когда пересекаются, выполнится только первое совпадение:

Выбор

Когда Возраст < 18 Тогда

Сообщить("Детский билет");

Когда Возраст < 25 Тогда // Это условие никогда не выполнится для возрастов 18-24!

Сообщить("Молодёжный билет");

КонецВыбора;

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

3. Сравнение ссылочных типов по значению

При работе со ссылками (например, СправочникСсылка.Номенклатура) сравнение по = может не сработать, если объекты разные, но имеют одинаковые реквизиты. Правильно:

Если Номенклатура1.Ссылка = Номенклатура2.Ссылка Тогда

// Правильное сравнение ссылок

КонецЕсли;

4. Использование сложных выражений в условиях

Если в блоке Когда указать выражение с побочными эффектами (например, вызов функции), оно будет выполняться даже если предыдущее условие уже сработало:

Выбор

Когда ПолучитьСтатусЗаказа(Заказ) = "Оплачен" Тогда // Функция вызовется всегда!

// ...

КонецВыбора;

Лучше заранее вычислить значение и сравнивать его:

Статус = ПолучитьСтатусЗаказа(Заказ);

Выбор

Когда Статус = "Оплачен" Тогда

// ...

КонецВыбора;

Что произойдёт, если не закрыть КонецВыбора?

В 1С 8.3 это приведёт к синтаксической ошибке на этапе компиляции модуля. Система выдаст сообщение "Ожидается 'КонецВыбора'" и укажет строку, где проблема. В отличие от некоторых языков (например, JavaScript), где отсутствие закрывающей скобки может привести к неявным ошибкам, в это всегда ловится на этапе проверки кода.

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

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

1. Располагайте условия по вероятности

Чаще выполняемые условия должны идти первыми. Например, если в 90% случаев статусом документа является "Согласован", поместите это условие первым:

Выбор

Когда Статус = "Согласован" Тогда // Частый случай

// ...

Когда Статус = "Отклонён" Тогда // Редкий случай

// ...

КонецВыбора;

2. Используйте хэш-таблицы для больших наборов данных

Если у вас десятки или сотни вариантов (например, обработка кодов регионов), Выбор-Когда станет неэффективным. Лучше использовать Соответствие:

КодыРегионов = Новый Соответствие;

КодыРегионов.Вставить(77, "Москва");

КодыРегионов.Вставить(78, "Санкт-Петербург");

// ...

Результат = КодыРегионов.Получить(КодРегиона, "Неизвестный регион");

3. Избегайте вычислений в условиях

Как упоминалось ранее, выражения в блоках Когда вычисляются всегда. Если вычисление ресурсоёмкое (например, запрос к базе), лучше вынести его за пределы конструкции.

4. Заменяйте на Если-Тогда при малом количестве условий

Для 2-3 вариантов Если-Тогда может быть быстрее из-за особенностей оптимизации платформы .

💡

Для 5+ условий Выбор-Когда обычно эффективнее цепочки Если-Тогда, но при 100+ вариантах рассмотрите альтернативные структуры данных (массивы, соответствия).

Работа с объектами 1С в Выбор-Когда

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

1. Сравнение ссылок на справочники

Частая задача — выполнение разных действий в зависимости от выбранной номенклатуры или контрагента:

Выбор

Когда Номенклатура.Ссылка = Справочники.Номенклатура.Услуга1 Тогда

Цена = 1000;

Когда Номенклатура.Ссылка = Справочники.Номенклатура.Услуга2 Тогда

Цена = 2000;

Когда Номенклатура.ЭтоГруппа() Тогда

ВызватьИсключение("Нельзя выбирать группу номенклатуры!");

КонецВыбора;

2. Проверка типов документов

При обработке коллекции документов разных типов:

Для Каждого Док Из МассивДокументов Цикл

Выбор

Когда ТипЗнч(Док) = Тип("Документ.ПоступлениеТоваров") Тогда

ОбработатьПоступление(Док);

Когда ТипЗнч(Док) = Тип("Документ.РеализацияТоваров") Тогда

ОбработатьРеализацию(Док);

КонецВыбора;

КонецЦикла;

3. Работа с перечислениями

Перечисления в идеально подходят для Выбор-Когда:

Выбор

Когда ВидОплаты = Перечисление.ВидыОплат.Наличные Тогда

Комиссия = 0;

Когда ВидОплаты = Перечисление.ВидыОплат.БанковскаяКарта Тогда

Комиссия = 1.5;

Когда ВидОплаты = Перечисление.ВидыОплат.ЭлектронныеДеньги Тогда

Комиссия = 2.0;

КонецВыбора;

Важно: при сравнении ссылок на объекты (например, справочников) всегда используйте оператор =, а не СокрЛП() или другие функции приведения типов. В противном случае сравнение может работать некорректно из-за особенностей хранения ссылок в .

Альтернативные подходы: когда Выбор-Когда не подходит

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

1. Сложные составные условия

Если условия включают логические операторы (И, Или, НЕ), лучше использовать Если-Тогда:

Если (Сумма > 1000 И Валюта = "USD") Или Клиент.ВипСтатус Тогда

ПрименитьСкидку(10);

КонецЕсли;

2. Диапазоны значений

Для проверки попадания в диапазон удобнее Если:

Если Возраст >= 18 И Возраст < 25 Тогда

Сообщить("Молодёжная категория");

КонецЕсли;

3. Динамические условия

Если условия формируются динамически (например, из настроек пользователя), используйте массивы или соответствия:

УсловияСкидок = Новый Соответствие;

УсловияСкидок.Вставить("ВипКлиент", 10);

УсловияСкидок.Вставить("ОптовыйЗаказ", 5);

// ...

Скидка = УсловияСкидок.Получить(ТипКлиента, 0);

4. Вложенные проверки

Выбор-Когда не поддерживает вложенные конструкции. Для многоуровневой логики комбинируйте Выбор-Когда и Если:

Выбор

Когда ТипДокумента = "Заказ" Тогда

Если Сумма > 10000 Тогда

Сообщить("Крупный заказ!");

КонецЕсли;

Когда ТипДокумента = "Возврат" Тогда

// ...

КонецВыбора;

📊 Какой альтернативный подход вы используете чаще?
Цепочка Если-Тогда
Массивы/Соответствия
Пользовательские функции
Другое

FAQ: Частые вопросы по Выбор-Когда в 1С

Можно ли использовать Выбор-Когда для проверки типа значения?

Да, это один из самых удобных сценариев. Пример:

Выбор

Когда ТипЗнч(Значение) = Тип("Число") Тогда

Сообщить("Это число: " + Значение);

Когда ТипЗнч(Значение) = Тип("Строка") Тогда

Сообщить("Это строка длиной " + СтрДлина(Значение));

КонецВыбора;

Такой подход часто используется в универсальных функциях обработки данных.

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

Используйте блок Иначе:

Выбор

Когда Условие1 Тогда

// ...

Когда Условие2 Тогда

// ...

Иначе

Сообщить("Неизвестное условие!"); // Выполнится, если ни одно из условий не сработало

КонецВыбора;

Если блок Иначе не указан, выполнение просто продолжится после КонецВыбора.

Можно ли использовать Выбор-Когда для обработки исключений?

Технически можно, но это не рекомендуется. Для обработки ошибок лучше использовать Попытка-Исключение:

Попытка

// Код, который может вызвать ошибку

Исключение

Выбор

Когда ТипЗнч(ОписаниеОшибки()) = Тип("ОшибкаПриВводеЗначения") Тогда

Сообщить("Некорректный ввод!");

Когда КодОшибки() = 1001 Тогда

Сообщить("Объект не найден");

КонецВыбора;

КонецПопытки;

Однако такой код сложно поддерживать — лучше разделять логику обработки ошибок и бизнес-логику.

Как оптимизировать Выбор-Когда с большим количеством условий (50+)?

Для большого числа условий (более 20-30) Выбор-Когда становится неэффективным. Альтернативы:

  • 📊 Используйте Соответствие (ассоциативный массив) для хранения вариантов.
  • 📊 Разбейте логику на несколько Выбор-Когда с группировкой условий.
  • 📊 Вынесите условия в отдельную таблицу базы данных и используйте запрос для получения результата.

Пример с Соответствием:

ДействияПоКодам = Новый Соответствие;

ДействияПоКодам.Вставить(100, "ОбработатьЗаказ");

ДействияПоКодам.Вставить(200, "ОтменитьЗаказ");

// ...

Действие = ДействияПоКодам.Получить(КодДействия, "НеизвестноеДействие");

Почему моя конструкция Выбор-Когда не работает с объектами?

Частая ошибка — сравнение объектов по значению вместо сравнения ссылок. Например:

// Некорректно (сравниваются значения, а не ссылки)

Когда Номенклатура1 = Номенклатура2 Тогда

// Корректно (сравниваются ссылки)

Когда Номенклатура1.Ссылка = Номенклатура2.Ссылка Тогда

Также убедитесь, что объекты не являются Неопределено — это может приводить к неожиданным результатам.

💡

Если вам нужно отладить работу Выбор-Когда, добавьте временное сообщение в каждый блок Когда и Иначе, чтобы увидеть, какое условие срабатывает. Например: Сообщить("Сработало условие 1: " + Условие1);

⚠️ Внимание: В некоторых версиях платформы 1С:Предприятие (особенно до 8.3.10) существовали баги с оптимизацией конструкции Выбор-Когда при большом количестве условий. Если вы работаете со старыми конфигурациями, тестируйте производительность на реальных данных.