К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как написать условие в 1С: полное руководство с примерами

Разбираем, как написать условие в 1С: оператор Если, условный оператор в запросах, выбор по условию, типичные ошибки сравнения и проверка результата.

Условие — базовая конструкция любого кода на встроенном языке 1С. С его помощью программа принимает решение: выполнить одну ветку алгоритма или другую, отобрать записи в запросе, вывести разный текст в печатной форме. Ошибка в условии приводит не к аварийной остановке, а к тихому неверному поведению: документ проведётся неправильно, скидка не применится, отчёт покажет чужие данные.

В 1С условия встречаются в трёх основных местах: оператор Если…Тогда…КонецЕсли в модуле, конструкция ГДЕ в тексте запроса и тернарный выбор ?(Условие, Значение1, Значение2) в выражениях. Синтаксис у них разный, и типичная ошибка новичка — переносить правила одного контекста в другой.

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

Оператор Если: базовый синтаксис условия в модуле

Основная форма условного оператора во встроенном языке 1С выглядит так:

Если СуммаДокумента > 100000 Тогда

ТребуетсяСогласование = Истина;

ИначеЕсли СуммаДокумента > 0 Тогда

ТребуетсяСогласование = Ложь;

Иначе

Сообщить("Сумма документа не заполнена");

КонецЕсли;

Ключевые правила: после Если идёт выражение, которое должно вычисляться в булево значение (Истина или Ложь), затем обязательное слово Тогда. Веток ИначеЕсли может быть сколько угодно, ветка Иначе — необязательна. Завершает конструкцию КонецЕсли; с точкой с запятой — её отсутствие даёт синтаксическую ошибку при проверке модуля.

Условия проверяются сверху вниз, и выполняется только первая подошедшая ветка. Поэтому порядок веток имеет значение: если поставить проверку СуммаДокумента > 0 раньше, чем СуммаДокумента > 100000, вторая ветка никогда не сработает. Располагайте более строгие условия выше.

Порядок действий
  1. 1
    Определите, какое выражение должно давать Истина или Ложь
  2. 2
    Запишите ветки от самого строгого условия к самому общему
  3. 3
    Добавьте ветку Иначе для непредусмотренных ситуаций
  4. 4
    Проверьте модуль через конфигуратор: наличие КонецЕсли и точек с запятой
  5. 5
    Протестируйте каждую ветку на граничных значениях

Операторы сравнения и логические связки

В условиях используются операторы сравнения =, <> (не равно), >, <, >=, <=. Сравнивать можно числа, строки, даты, ссылки и булевы значения. Строки сравниваются с учётом регистра: "Акт" и "акт" — разные значения.

Сложные условия строятся логическими операторами:

  • И — истинно, когда истинны обе части;
  • ИЛИ — истинно, когда истинна хотя бы одна часть;
  • НЕ — инвертирует значение.
Если (Статус = "Оплачен" И Сумма > 0)

ИЛИ РежимРучнойКорректировки Тогда

РазрешитьПроведение = Истина;

КонецЕсли;

Приоритет операторов: сначала НЕ, затем И, затем ИЛИ. Смешивая И и ИЛИ без скобок, легко получить не ту логику, которую задумывали. Правило простое: любое сочетание разных логических операторов закрывайте скобками — это убирает двусмысленность и для компилятора, и для читающего код.

Типичные ошибки
01
Присваивание вместо сравнения: в 1С одиночное = в условии — это сравнение, но при чтении кода его легко спутать с присваиванием; пишите условие так, чтобы порядок операндов был очевиден
02
Смешение И и ИЛИ без скобок: условие срабатывает не в тех случаях, и ошибка всплывает только на редких данных
03
Сравнение ссылки со строкой: Ссылка = "Номенклатура" всегда ложно, сравнивать нужно с конкретной ссылкой или использовать ТипЗнч()
04
Проверка пустой даты сравнением с 0: правильно — сравнение с '00010101' или функцией ЗначениеЗаполнено()

Тернарный оператор и Выбор в выражениях

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

ТекстСтатуса = ?(ДокументПроведен, "Проведён", "Черновик");

Оператор читается как «если условие истинно — первое значение, иначе второе». Он удобен при формировании строк, установке реквизитов и в выражениях, где полноценный Если не вставить. Не стоит вкладывать тернарные операторы друг в друга: конструкция ?(А, 1, ?(Б, 2, 3)) работает, но читается плохо — при трёх и более ветках возвращайтесь к Если…ИначеЕсли.

В языке запросов аналогичную роль играет конструкция ВЫБОР КОГДА … ТОГДА … ИНАЧЕ … КОНЕЦ, которая позволяет вычислять значение поля по условию прямо в выборке. Это удобно, когда нужно в одном запросе получить, например, признак «Просрочен» по сравнению даты оплаты с текущей датой.

Сравнение вариантов

Если…Тогда…КонецЕсли

Подходит для любой логики и нескольких операторов в ветке; ограничение — многословность для простого выбора значения

Тернарный ?(Условие, А, Б)

Лучший вариант для выбора одного из двух значений в выражении; не подходит для веток с несколькими операторами

ВЫБОР в запросе

Единственный способ условного вычисления поля внутри запроса; не работает в обычном коде модуля

Условия в запросах: ГДЕ, параметры и виртуальные таблицы

В тексте запроса условие отбора записывается в секции ГДЕ:

ВЫБРАТЬ

Номенклатура, Количество

ИЗ

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

ГДЕ

Количество > 0

Параметры передаются через &ИмяПараметра и устанавливаются методом УстановитьПараметр до выполнения запроса. Не подставляйте значения конкатенацией строк — это и источник ошибок с типами, и потенциальная уязвимость.

Важная оптимизационная деталь: условия на измерения виртуальной таблицы (остатки, обороты, срезы) указывайте в параметрах самой виртуальной таблицы, как в примере выше, а не в секции ГДЕ. Отбор в параметрах выполняется до расчёта виртуальной таблицы, в ГДЕ — после, что на больших объёмах данных заметно медленнее.

Для отбора по списку значений используйте оператор В (&СписокЗначений), для иерархии — В ИЕРАРХИИ (&Группа), для подстроки — ПОДОБНО "%текст%". Учтите, что ПОДОБНО с шаблоном, начинающимся с %, не использует индекс и на больших таблицах работает медленно.

Проверка пустых значений, Неопределено и NULL

Отдельный класс условий — проверка «заполненности». В 1С есть три разных «пустых» состояния, и путать их нельзя:

  • Неопределено — значение не присвоено. Проверка: Если Значение = Неопределено Тогда.
  • Пустая ссылка — ссылка заданного типа без объекта. Проверка: Если Контрагент.Пустая() Тогда или функция ЗначениеЗаполнено(Контрагент).
  • NULL — отсутствие значения в результате запроса (например, при левом соединении). Проверка только в запросе: ЕСТЬ NULL или функция ЕСТЬNULL(Поле, ЗначениеПоУмолчанию).

Универсальный вариант для кода модуля — функция ЗначениеЗаполнено(Значение): она возвращает Ложь для Неопределено, пустых ссылок, пустых строк, нулевых чисел и пустых дат. Но помните: число 0 и пустая дата — иногда вполне осмысленные значения, и отбрасывать их функцией ЗначениеЗаполнено бывает ошибкой бизнес-логики.

В запросе сравнение с NULL через = не работает: результат всегда неопределён, и строка в выборку не попадёт. Только ЕСТЬ NULL / НЕ ЕСТЬ NULL. Это одна из самых частых причин «запрос ничего не вернул, хотя данные есть».

Как проверить, что условие работает правильно

Проверка условия начинается с граничных значений. Для условия Сумма > 100000 тестируют значения 99999, 100000, 100001 и 0: именно на границе чаще всего обнаруживается, что нужно было >=, а не >. Каждая ветка Если и ИначеЕсли должна быть достигнута хотя бы в одном тесте.

Для отладки используйте точку останова в конфигураторе и вычисление выражения (Shift+F9): можно проверить, во что реально вычисляется условие на конкретных данных, не догадываясь. Если условие сложное, временно разбейте его на переменные с говорящими именами — ЭтоОплаченныйЗаказ, ПревышенЛимит — и проверяйте каждую по отдельности.

Для запросов удобен конструктор запроса и консоль запросов в режиме предприятия: выполните запрос с реальными параметрами, затем по одному убирайте условия из ГДЕ, чтобы найти то, которое отсекает нужные строки. Если запрос возвращает меньше записей, чем ожидалось, первым делом проверяйте соединения (левое/внутреннее) и сравнения с NULL.

Контрольные точки

Как проверить результат

Выполнение каждой ветки условия
Норма

Каждая ветка достигается хотя бы на одном тестовом наборе данных

Тревожный признак

Ветка Иначе или ИначеЕсли не выполняется никогда — вероятно, условия перекрывают друг друга

Граничные значения
Норма

На значении ровно на границе срабатывает задуманная ветка

Тревожный признак

Граница попадает не в ту ветку — перепутаны &gt; и &gt;=

Результат запроса
Норма

Количество записей соответствует ожиданию на контрольном примере

Тревожный признак

Записей меньше — проверяйте NULL, типы параметров и вид соединения

Частые ошибки и как их избежать

Самая коварная группа ошибок — сравнение значений разных типов. Сравнение строки с числом или ссылки со строкой не вызывает исключения, а просто даёт Ложь, и условие молча не срабатывает. Перед сравнением убедитесь в типах: используйте ТипЗнч(Значение) или явное приведение.

Вторая группа — условия, зависящие от контекста исполнения. Код, работающий на клиенте, не видит серверные функции и наоборот; директивы &НаСервере и &НаКлиенте определяют, какие данные доступны в условии. Проверка существования объекта по ссылке требует серверного контекста.

Третья группа — избыточная вложенность. Пять вложенных Если подряд читаются хуже, чем плоская цепочка с ранним выходом: Если НЕ Условие Тогда Возврат; КонецЕсли;. Приём «защитного выхода» упрощает и код, и его тестирование.

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

FAQ

Чем отличается = от == в 1С?

Во встроенном языке 1С оператора == нет. Одиночный знак равенства используется и для присваивания, и для сравнения — контекст определяется положением: в условии после Если это сравнение, в начале оператора — присваивание.

Как проверить, что строка не пустая?

Используйте НЕ ПустаяСтрока(Строка) — функция считает пустой и строку из одних пробелов. Функция ЗначениеЗаполнено() для строки из пробелов вернёт Истина, что не всегда ожидаемо.

Можно ли в условии сравнивать даты?

Да, даты сравниваются операторами >, <, = напрямую. Помните, что дата содержит время с точностью до секунды: сравнение на равенство двух дат, полученных разными способами, может не сработать из-за разного времени. Для сравнения по дню используйте НачалоДня() или КонецДня().

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

Для отбора по списку нужен оператор В: ГДЕ Номенклатура В (&СписокНоменклатуры), а параметру должен быть присвоен массив или список значений. Сравнение через = со списком не сработает.

Как написать условие «если поле заполнено, то фильтровать, иначе показать всё» в запросе?

Шаблон: ГДЕ (&Параметр = НЕОПРЕДЕЛЕНО ИЛИ Поле = &Параметр) — при неустановленном параметре отбор отключается. Перед выполнением не забывайте устанавливать параметр в Неопределено, если фильтр не нужен.

Что вернёт сравнение с NULL в запросе через знак равно?

Результат будет неопределённым, и такая строка не попадёт в выборку — условие просто «не сработает» без ошибки. Для проверки на NULL используйте конструкцию Поле ЕСТЬ NULL или функцию ЕСТЬNULL().

Итог

Что важно запомнить

В модуле условие пишется через Если…Тогда…КонецЕсли, в запросе — через ГДЕ и ВЫБОР, в выражениях — через тернарный ?(). Следите за типами сравниваемых значений, разделяйте Неопределено, пустую ссылку и NULL, ставьте скобки при смешении И и ИЛИ, а изменения логики проведения проверяйте на копии базы.