При переходе на платформу 1С:Предприятие разработчики, имеющие опыт работы с языками семейства C (C++, C#, Java, JavaScript), часто сталкиваются с неожиданным поведением базовых операторов. Одним из таких камней преткновения становится оператор присваивания. В этой статье мы подробно разберем, почему привычные конструкции вида А = Б = В в 1С работают не так, как ожидается, и как правильно писать код, чтобы избежать логических ошибок.
Рассмотрим ситуацию, описанную автором вопроса. Программист пытается в одну строку установить свойство Доступность для двух элементов формы:
Элементы.ПересчитыватьЦены.Доступность = Элементы.ПроцентПересчетаЦены.Доступность = Ложь;
В языках вроде C++ такая запись означала бы, что сначала переменной Элементы.ПроцентПересчетаЦены.Доступность присваивается значение Ложь, а затем результат этой операции (то есть тоже Ложь) присваивается переменной Элементы.ПересчитыватьЦены.Доступность. В итоге оба элемента стали бы недоступны.
Однако в 1С результат будет иным. Проанализируем, как интерпретатор 1С читает эту строку. В языке 1С символ = выполняет две принципиально разные роли: оператора присваивания и оператора сравнения. Логика парсера системы такова:
= в инструкции (если это не условие Если или Пока) всегда считается оператором присваивания.= в этой же строке интерпретируются как логические операторы сравнения ("Равно").Таким образом, выражение превращается в следующую логическую конструкцию:
Переменная_1 = (Переменная_2 = Значение)
Сначала вычисляется правая часть: Элементы.ПроцентПересчетаЦены.Доступность = Ложь. Это логическое выражение. Если свойство Доступность в данный момент равно Истина, то результат сравнения будет Ложь. Если свойство уже было равно Ложь, то результат сравнения будет Истина. Затем этот булев результат (Истина или Ложь) присваивается первому элементу. В итоге мы получаем не массовое присваивание значения Ложь, а непредсказуемое изменение состояния первого элемента в зависимости от текущего состояния второго.
Выясним фундаментальную причину, почему поведение 1С отличается от C-образных языков. В C++ присваивание является выражением, которое возвращает присвоенное значение. Это позволяет вкладывать присваивания друг в друга.
В языке 1С присваивание — это инструкция (оператор), а не выражение. Инструкция присваивания в 1С не возвращает никакого значения и не может быть частью другого выражения. Это роднит 1С с такими языками, как Pascal или Basic. Поскольку 1С проектировалась как система с низким порогом входа, разработчики платформы предпочли строгую структуру кода, исключающую неоднозначности, которые могут возникнуть при использовании сложных выражений с побочными эффектами.
Проанализируем единственный верный способ решения задачи в среде 1С. Чтобы гарантированно присвоить одно и то же значение нескольким объектам или переменным, необходимо использовать последовательную запись. Разберем по шагам правильный подход:
// Устанавливаем доступность для первого элемента
Элементы.ПересчитыватьЦены.Доступность = Ложь;
// Устанавливаем доступность для второго элемента
Элементы.ПроцентПересчетаЦены.Доступность = Ложь;
Хотя такой код занимает больше строк, он обладает неоспоримыми преимуществами:
Рассмотрим еще один важный момент, упомянутый в обсуждении — отсутствие операторов i++ или i--. В 1С нельзя использовать краткие формы изменения значения переменной, такие как +=, -= или ++. Посмотрим на примере, как нужно изменять счетчик:
// Вместо привычного сишникам i++;
Счетчик = Счетчик + 1;
// Вместо Сумма += Цена;
Сумма = Сумма + Цена;
Это часть общей философии языка: явное всегда лучше неявного. Полная запись операции изменения переменной снижает вероятность ошибок, связанных с приоритетом операций в сложных выражениях.
Поскольку мы выяснили, что вторая часть выражения А = Б = В является логическим сравнением, важно помнить, как именно 1С сравнивает данные различных типов, чтобы не получить неожиданный результат Ложь:
"Склад" = "Склад " вернет Истина.0 и значения Ложь) в 1С всегда дает Ложь, в отличие от JavaScript, где типы могут приводиться друг к другу.Подведем итог: если вы хотите написать качественный и стабильный код в 1С, откажитесь от привычки использовать «красивые» цепочки присваивания. Помните, что в 1С первый символ = — это действие, а все последующие — вопрос ("равно ли?"). Пишите код пошагово, разделяя операции присваивания на отдельные строки, и ваша конфигурация будет работать именно так, как вы задумали.