Условия в 1С: оператор Если, тернарник и ВЫБОР в запросе
Содержание
Условие в 1С задаётся двумя разными инструментами, и выбор зависит от того, где вы пишете код. Во встроенном языке ветвление делает оператор Если … Тогда … КонецЕсли, а в тексте запроса — секция ГДЕ для отбора строк и выражение ВЫБОР КОГДА … ТОГДА … ИНАЧЕ … КОНЕЦ для вычисляемых полей.
Логику внутри условия собирают из сравнений (=, <>, >, <, >=, <=) и логических операторов И, ИЛИ, НЕ. Для короткой проверки «одно значение или другое» есть тернарный оператор ?(). Ниже — синтаксис каждого способа с рабочими примерами и таблица, когда какой применять.
Всё описанное относится к платформе 1С:Предприятие 8.3 и встроенному языку — он одинаков в Бухгалтерии, ЗУП, Управлении торговлей и любой другой конфигурации.
Оператор Если: основное ветвление во встроенном языке
Базовая конструкция состоит из ключевого слова Если, самого условия, слова Тогда и блока команд. Завершается всё обязательным КонецЕсли с точкой с запятой.
Если Сумма > 1000 Тогда
Скидка = 10;
КонецЕсли;
Если нужно обработать противоположный случай, добавляют ветку Иначе. Она срабатывает, когда условие ложно.
Если Контрагент.ЮрЛицо Тогда
СтавкаНДС = СтавкаНДС20;
Иначе
СтавкаНДС = БезНДС;
КонецЕсли;
Для нескольких взаимоисключающих вариантов используют цепочку ИначеЕсли. Платформа проверяет условия сверху вниз и выполняет первый подошедший блок, остальные пропускает.
Если Количество > 100 Тогда
Категория = "Крупный опт";
ИначеЕсли Количество > 10 Тогда
Категория = "Мелкий опт";
ИначеЕсли Количество > 0 Тогда
Категория = "Розница";
Иначе
Категория = "Нет остатка";
КонецЕсли;
Отдельного оператора Выбор/switch, как в некоторых языках, во встроенном языке 1С нет. Многовариантный выбор делают именно цепочкой ИначеЕсли. Слово ВЫБОР существует только в языке запросов — о нём ниже.
Условие может ссылаться на реквизиты объекта, переменные, результат функции — на любое выражение, которое возвращает Истина или Ложь. Булев реквизит (флажок) подставляют прямо, без сравнения с Истина:
Если Документ.Проведён Тогда // так правильно
Если Документ.Проведён = Истина Тогда // так избыточно, хотя тоже работает
Логические операторы И, ИЛИ, НЕ
Когда в условии несколько проверок, их соединяют логическими операторами. В 1С их три:
- ✅
И— истинно, когда истинны оба операнда (логическое умножение). - ✅
ИЛИ— истинно, когда истинен хотя бы один операнд. - ✅
НЕ— инвертирует значение:НЕ ИстинадаётЛожь.
Если (Статус = "Оплачен") И НЕ Заказ.Отменён Тогда
Отгрузить = Истина;
КонецЕсли;
Приоритет такой: сначала НЕ, затем И, затем ИЛИ. Из-за этого выражение без скобок читается не всегда так, как задумано. Сравните:
// A ИЛИ B И C платформа понимает как A ИЛИ (B И C)
Если Срочно ИЛИ Сумма > 1000 И Предоплата Тогда
Чтобы не держать приоритеты в голове, ставьте скобки вокруг каждой группы — это убирает двусмысленность и ошибки, которые потом тяжело ловить:
Если Срочно ИЛИ (Сумма > 1000 И Предоплата) Тогда
Ещё одна особенность — «ленивое» вычисление. В связке через И платформа не проверяет второй операнд, если первый уже Ложь. Это удобно для защиты от обращения к пустой ссылке:
Если ЗначениеЗаполнено(Контрагент) И Контрагент.ЮрЛицо Тогда
Здесь Контрагент.ЮрЛицо вычислится только после того, как первая проверка подтвердит, что ссылка заполнена. Поменяете части местами — получите ошибку на пустом значении.
Тернарный оператор ?() — условие в одну строку
Когда нужно не выполнить команды, а просто выбрать одно из двух значений, разворачивать Если … КонецЕсли на пять строк необязательно. Для этого есть тернарный оператор:
?(Условие, ЗначениеЕслиИстина, ЗначениеЕслиЛожь)
Он возвращает второй аргумент, если условие истинно, и третий — если ложно.
Скидка = ?(Сумма > 1000, 10, 0);
Обращение = ?(Пол = Перечисления.Пол.Мужской, "Уважаемый", "Уважаемая");
Тернарник удобен прямо внутри других выражений — например, при сборке строки сообщения или при заполнении реквизита:
Сообщить("Заказ " + Номер + ?(Срочно, " (СРОЧНО)", ""));
Не вкладывайте тернарники друг в друга на три-четыре уровня: ?(A, 1, ?(B, 2, ?(C, 3, 4))) читается тяжело. Для трёх и более вариантов возьмите обычную цепочку ИначеЕсли — её проще сопровождать.
Условие отбора в запросе: секция ГДЕ
В языке запросов ветвление устроено иначе. Чтобы оставить в выборке только нужные строки, после источника данных пишут секцию ГДЕ с условием. Логические операторы те же — И, ИЛИ, НЕ.
ВЫБРАТЬ
Номенклатура.Наименование,
Номенклатура.Артикул
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
НЕ Номенклатура.ПометкаУдаления
И Номенклатура.Родитель = &ГруппаТовары
Значения, которые приходят извне (из формы, из кода), подставляют через параметры — имя с амперсандом: &ГруппаТовары, &ДатаНачала. Их значения задаются методом УстановитьПараметр у объекта запроса.
Для диапазонов и списков есть специальные конструкции:
ГДЕ
Продажи.Дата МЕЖДУ &ДатаНачала И &ДатаКонца
И Продажи.Склад В (&СписокСкладов)
И Продажи.Контрагент ССЫЛКА Справочник.Контрагенты
Для условия по части строки берут оператор ПОДОБНО с шаблоном, где % заменяет любое число символов, а _ — один:
ГДЕ
Номенклатура.Наименование ПОДОБНО "%кабель%"
Так отберутся все позиции, в названии которых встречается «кабель». Проверку на пустую ссылку в условии отбора делают сравнением с пустым значением соответствующего типа: ГДЕ Документ.Склад <> ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка).
Конструктор запроса вместо ручного набора
Текст запроса редко пишут руками с нуля. В Конфигураторе и в режиме «Предприятие» (консоль запросов, обработки разработчика) есть конструктор запроса — визуальный редактор. Его вызывают из контекстного меню строки с текстом запроса командой Конструктор запроса.
Условия задаются на вкладке Условия: перетаскиваете поле, выбираете операцию сравнения, указываете значение или параметр. Конструктор сам соберёт корректную секцию ГДЕ и расставит скобки. Это удобно, пока условий немного; сложную логику с вложенными ИЛИ всё равно проще дописать руками в тексте.
Выражение ВЫБОР КОГДА: условие прямо в поле запроса
Секция ГДЕ отбирает строки целиком. А если нужно в самом поле вычислить значение по условию — например, вывести текстовую метку вместо числа, — применяют конструкцию ВЫБОР. Это аналог Если внутри запроса.
ВЫБРАТЬ
Товары.Номенклатура,
ВЫБОР
КОГДА Товары.Количество > 100 ТОГДА "Много"
КОГДА Товары.Количество > 10 ТОГДА "Средне"
КОГДА Товары.Количество > 0 ТОГДА "Мало"
ИНАЧЕ "Нет в наличии"
КОНЕЦ КАК Доступность
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки КАК Товары
Правила те же, что у ИначеЕсли: условия КОГДА проверяются по очереди, срабатывает первое истинное. Ветка ИНАЧЕ необязательна — если её нет и ни одно КОГДА не подошло, поле получит NULL.
Выражение ВЫБОР можно использовать не только для вывода, но и в группировке, упорядочивании, в условиях соединений. Частый приём — считать количество строк, удовлетворяющих условию, через сумму единиц и нулей:
СУММА(ВЫБОР КОГДА Продажи.Сумма > 0 ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) КАК КоличествоПродаж
Условное оформление: условие без кода
В динамических списках, табличных документах и формах цвет, шрифт или видимость часто задают по условию — и для этого писать код не нужно. Механизм называется условное оформление.
В настройках списка или отчёта (компоновка данных) открываете вкладку Условное оформление и добавляете элемент. В нём три блока:
- Оформление — что меняем: цвет текста, фон, шрифт, формат.
- Условие — при каком значении поля оформление применится (то же сравнение полей, что в отборе).
- Оформляемые поля — к каким колонкам применить.
Пример: выделить красным фоном строки, где Остаток < 0. Задаёте поле Остаток, вид сравнения Меньше, значение 0 — и платформа подсветит нужные строки сама, без обработчиков.
Условное оформление считается на стороне компоновки и не тормозит форму. Если то же самое делать кодом в обработчике ПриВыводеСтроки, на больших списках это заметно медленнее.
Проверка значений: Неопределено, NULL и защита от ошибок
Условие часто падает не из-за логики, а из-за того, что сравниваемое значение «пустое». В 1С пустота бывает разной, и путать её нельзя:
Неопределено— значение не задано (пустая переменная, несуществующий реквизит).NULL— приходит из запроса, когда в соединении нет данных или нет веткиИНАЧЕ.- Пустая ссылка, пустая строка,
0,Ложь— это заполненные, но «нулевые» значения.
Проверять заполненность во встроенном языке удобнее всего функцией ЗначениеЗаполнено() — она возвращает Ложь сразу для Неопределено, NULL, пустой ссылки, пустой строки и нулевой даты:
Если ЗначениеЗаполнено(Контрагент) Тогда
// ссылка точно не пустая
КонецЕсли;
В запросах NULL нельзя сравнивать через =. Для него есть отдельная функция ЕСТЬNULL(Поле, ЗначениеПоУмолчанию), которая подменяет пустоту на нужное значение:
ВЫБРАТЬ
ЕСТЬNULL(Остатки.Количество, 0) КАК Количество
Отдельная история — ошибки времени выполнения: деление на ноль, конвертация строки в число, обращение к недоступному сервису. Их перехватывают конструкцией Попытка … Исключение … КонецПопытки. Код в блоке Попытка выполняется, и если возникает ошибка, управление уходит в Исключение, а программа не падает.
Попытка
Коэффициент = Выручка / Количество;
Исключение
Коэффициент = 0;
ЗаписьЖурналаРегистрации("Расчёт", УровеньЖурналаРегистрации.Ошибка,
, , ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Не превращайте Попытка в «глушилку» ошибок с пустым блоком Исключение — так вы прячете реальные сбои. Перехватывайте только то, что действительно может возникнуть, и обязательно пишите причину в журнал регистрации через ИнформацияОбОшибке().
Какой способ условия выбрать
Инструментов несколько, и каждый — под свою задачу. Короткая шпаргалка:
| Задача | Инструмент | Где пишется |
|---|---|---|
| Выполнить разные команды | Если … ИначеЕсли … КонецЕсли | Встроенный язык |
| Выбрать одно из двух значений | Тернарный ?() | Встроенный язык |
| Оставить нужные строки выборки | Секция ГДЕ | Запрос |
| Вычислить значение поля по условию | ВЫБОР КОГДА … КОНЕЦ | Запрос |
Подменить NULL в запросе | ЕСТЬNULL() | Запрос |
| Покрасить строки/ячейки по условию | Условное оформление | Настройка списка/отчёта |
| Защититься от ошибки выполнения | Попытка … Исключение | Встроенный язык |
Общий принцип: отбор и расчёт по условию старайтесь делать в запросе, а не в цикле по выборке — база обрабатывает это гораздо быстрее, чем перебор строк кодом. Оформление по условию держите в настройках компоновки, а обработчики кода оставляйте для того, что иначе не сделать.
Частые вопросы
Можно ли во встроенном языке 1С написать switch или case?
ИначеЕсли. Слово ВЫБОР есть только в языке запросов — это выражение ВЫБОР КОГДА … ТОГДА … ИНАЧЕ … КОНЕЦ, которое возвращает значение, а не выполняет команды.Почему условие с ИЛИ и И работает не так, как я ожидал?
НЕ, затем И, и только потом ИЛИ. Выражение A ИЛИ B И C платформа читает как A ИЛИ (B И C). Ставьте скобки вокруг каждой логической группы — результат станет однозначным.Как в условии проверить, что реквизит не заполнен?
ЗначениеЗаполнено(): она сразу отсекает Неопределено, NULL, пустую ссылку, пустую строку и нулевую дату. В запросе пустое значение после соединения приходит как NULL, и сравнивать его через = нельзя — используйте ЕСТЬNULL(Поле, 0).В чём разница между секцией ГДЕ и выражением ВЫБОР в запросе?
ГДЕ фильтрует: отбирает строки, которые попадут в результат. ВЫБОР КОГДА вычисляет: формирует значение в конкретном поле, оставляя все строки на месте. Их часто используют вместе.Как задать условие, чтобы выделить строки списка цветом?
Условное оформление, добавьте элемент: задайте оформление (цвет, шрифт), условие по полю и колонки, к которым применить. Платформа подсветит строки сама.