Как работает двойное равенство в 1С и как правильно использовать присваивание и сравнение в одной строке

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки во встроенном языке «1С:Предприятие» программисты часто сталкиваются с лаконичными конструкциями, которые вызывают вопросы, особенно у тех, кто имеет опыт работы с другими языками программирования (например, C++, C#, Java, JavaScript или Pascal). Одним из таких примеров является использование нескольких знаков равенства = в рамках одной инструкции. Рассмотрим классический пример такой строки кода:


Результат = ПредЗадача.Результат = Перечисления.РезультатВыполненияЗадачи.Согласовано;

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

Принцип работы платформы 1С: разделение ролей знака равенства

В отличие от многих других языков программирования, где для присваивания и сравнения используются принципиально разные символы (например, в Си-подобных языках присваивание — это =, а сравнение — ==; в Pascal присваивание — это :=, а сравнение — =), в языке 1С для обеих этих операций применяется один и тот же символ — =.

Чтобы понять, какую именно операцию нужно выполнить в конкретный момент, транслятор 1С анализирует позицию знака равенства в строке инструкции. Логика платформы работает по следующим правилам:

  1. Первый встреченный знак равенства в инструкции всегда интерпретируется как оператор присваивания. Он указывает платформе, что значение всего выражения, расположенного справа от этого знака, необходимо вычислить и записать в переменную, имя которой указано слева от него.
  2. Все последующие знаки равенства в этой же инструкции воспринимаются системой исключительно как операторы сравнения. Результатом работы такого оператора всегда является булево значение — либо Истина, либо Ложь.

Вернемся к нашему примеру:


Результат = ПредЗадача.Результат = Перечисления.РезультатВыполненияЗадачи.Согласовано;

Проанализируем эту инструкцию по шагам, как это делает платформа:

  1. Интерпретатор видит первый знак = после переменной Результат. Он понимает: «Всё, что находится правее этого знака, нужно вычислить, а итог присвоить переменной Результат».
  2. Далее система начинает вычислять правую часть выражения: ПредЗадача.Результат = Перечисления.РезультатВыполненияЗадачи.Согласовано.
  3. Встретив второй знак =, платформа распознает его как оператор сравнения на равенство. Она сопоставляет текущее значение реквизита ПредЗадача.Результат со значением перечисления Перечисления.РезультатВыполненияЗадачи.Согласовано.
  4. Если эти значения совпадают, результатом сравнения становится булево значение Истина. Если не совпадают — значение Ложь.
  5. Полученный булев результат (Истина или Ложь) записывается в переменную Результат, находящуюся в самом начале строки.

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

Почему множественное присваивание в 1С невозможно?

Разработчики, пришедшие из сферы веб-разработки или системного программирования, могут ожидать от конструкции со множеством знаков равенства поведения в стиле языка Си. Например, в Си выражение a = b = c = 3; выполняет последовательное присваивание значения 3 справа налево: сначала переменной c присваивается 3, затем результат этой операции (тоже 3) присваивается b, и в конце — переменной a. В итоге все три переменные становятся равны 3.

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

Рассмотрим, что произойдет, если мы напишем выражение вида:

а = б = в = г;

Допустим, изначально в переменных хранятся числовые значения: б = 5, в = 5, г = 5. Выполнение будет происходить по строгой логике платформы:

  1. Первый знак = определяет, что переменной а будет присвоено значение выражения б = в = г.
  2. Выражение справа вычисляется последовательно слева направо.
  3. Сначала выполняется первое сравнение: б = в. Поскольку оба значения равны 5, результатом этой операции становится булево значение Истина.
  4. Далее система пытается сравнить полученный булев результат со значением переменной г. Фактически строка превращается в сравнение: Истина = г.
  5. Поскольку в переменной г хранится число 5, а слева от знака сравнения находится логическое значение Истина, платформа 1С попытается сравнить два разных типа данных.
  6. В этот момент программа аварийно завершит работу, выдав ошибку времени выполнения (Runtime Error): «Операции сравнения допустимы только над значениями совпадающих базовых типов». В 1С жестко запрещено прямое сравнение простых разнородных типов (чисел, строк, дат и булевых значений).

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

Рекомендации стандартов разработки 1С (Code Style)

Хотя конструкция Результат = ПредЗадача.Результат = Перечисления.РезультатВыполненияЗадачи.Согласовано; полностью работоспособна и успешно компилируется платформой, писать код в таком виде крайне не рекомендуется. Подобный синтаксис нарушает правила хорошего тона разработки и снижает читаемость конфигурации.

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

Вариант 1. Явное выделение логического выражения скобками (Рекомендуемый способ)

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


Результат = (ПредЗадача.Результат = Перечисления.РезультатВыполненияЗадачи.Согласовано);

Этот вариант является наиболее предпочтительным согласно стандартам разработки фирмы «1С». Он сохраняет лаконичность кода (всего одна строка), но полностью исключает двусмысленность при чтении.

Вариант 2. Использование сокращенного условного оператора (Тернарный оператор)

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


Результат = ?(ПредЗадача.Результат = Перечисления.РезультатВыполненияЗадачи.Согласовано, Истина, Ложь);

Хотя эта запись длиннее, она максимально прозрачна для разработчиков с любым бэкграундом. Сразу видно, что переменной Результат будет присвоено либо значение Истина, либо Ложь в зависимости от успешности проверки.

Вариант 3. Классическая условная конструкция Если...Тогда

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


Если ПредЗадача.Результат = Перечисления.РезультатВыполненияЗадачи.Согласовано Тогда
    Результат = Истина;
Иначе
    Результат = Ложь;
КонецЕсли;

Преимущества данного подхода: максимальная читаемость и простота отладки. Вы можете легко поставить точку останова на каждую из ветвей выполнения и сразу увидеть, по какому пути пошла программа. Однако для простых присваиваний этот вариант может выглядеть избыточно громоздким, увеличивая объем модуля на 5 строк вместо одной.

Резюме

Мы выяснили, что использование двойного равенства в 1С — это абсолютно легальная с точки зрения компилятора конструкция, где первый знак = выполняет присваивание, а второй — сравнение. Тем не менее, для поддержания высокой культуры кодинга всегда оборачивайте логическую часть выражения в круглые скобки. Это убережет вашу команду от путаницы при проведении код-ревью и сделает вашу конфигурацию более надежной и простой в сопровождении.

← На главную