В практике разработки на платформе 1С программисты часто сталкиваются с ситуацией, когда программный код ведет себя «непредсказуемо»: условие Если...Тогда срабатывает не так, как ожидалось, хотя отладчик показывает верные значения переменных. Разберем детально причины возникновения таких ошибок на примере конкретного кейса с форума, проанализируем приоритеты операций и выработаем стандарты написания надежного кода.
Рассмотрим ситуацию, с которой столкнулся автор темы. У него было условие, которое проверяло код товара и значение перечисления (Да/Нет). На первый взгляд код выглядел логично, но работал некорректно. Выясним причину, проанализировав структуру условия:
Если Товар.Код = "у45544" Или Товар.Код = "у45644" Или Товар.Код = "у45744" И Продажа = Перечисления.ДаНет.Да Тогда
// Действие
КонецЕсли;
Проблема здесь заключается в приоритете логических операций. В языке 1С (как и в большинстве языков программирования) логическое И имеет более высокий приоритет, чем ИЛИ. Это означает, что система интерпретирует выражение не последовательно слева направо, а сначала группирует части, связанные через И.
В нашем примере система видит это так:
Товар.Код = "у45544"Товар.Код = "у45644"(Товар.Код = "у45744" И Продажа = Да)Таким образом, если код товара равен "у45544", всё условие целиком становится истинным независимо от того, что выбрано в поле «Продажа». Чтобы логика работала верно, мы должны явно указать порядок вычисления с помощью скобок. Рассмотрим исправленный вариант:
Если (Товар.Код = "у45544" Или Товар.Код = "у45644" Или Товар.Код = "у45744") И Продажа = Перечисления.ДаНет.Да Тогда
// Теперь условие сработает только если код совпал И выбрано "Да"
КонецЕсли;
В исходном вопросе автор использовал конструкцию Строка(Продажа) = "Да". Это крайне нерекомендуемый подход в профессиональной разработке. Разберем по шагам, почему прямое сравнение с объектом Перечисления лучше преобразования в строку.
Во-первых, это вопрос локализации. Если ваша база данных будет запущена на сервере с другой языковой раскладкой или пользователь сменит язык интерфейса, функция Строка() для значения Перечисления.ДаНет.Да может вернуть "Yes" вместо "Да". В этом случае условие просто перестанет работать, хотя данные в базе не менялись.
Во-вторых, производительность. Сравнение двух ссылок (внутренних идентификаторов 1С) происходит мгновенно на уровне платформы. Преобразование объекта в строку требует дополнительных ресурсов памяти и процессорного времени на приведение типов.
Правильный способ сравнения:
// Плохо:
Если Строка(Продажа) = "Да" Тогда ...
// Хорошо:
Если Продажа = Перечисления.ДаНет.Да Тогда ...
Еще одна частая причина, по которой условие «не видит» данные — это специфика хранения строковых кодов в справочниках 1С. Если для справочника установлено свойство «Фиксированная длина», платформа будет дополнять код пробелами до указанной длины.
Например, если длина кода 10, а вы ввели "у45544", фактически в базе будет храниться строка "у45544 ". Прямое сравнение Товар.Код = "у45544" вернет Ложь, так как строки разной длины не равны.
Чтобы избежать этой ошибки, всегда используйте функцию СокрЛП() (сократить левые и правые пробелы) при сравнении кодов:
Если СокрЛП(Товар.Код) = "у45544" Тогда
// Код найден успешно, несмотря на лишние пробелы в базе
КонецЕсли;
Когда нам нужно проверить соответствие товара одному из множества кодов, конструкция с множественными ИЛИ становится громоздкой и трудночитаемой. Рассмотрим более изящный способ решения задачи через массив или список значений.
Проанализируем пример использования массива:
// Создаем список нужных нам кодов
СписокНужныхКодов = Новый Массив;
СписокНужныхКодов.Добавить("у45544");
СписокНужныхКодов.Добавить("у45644");
СписокНужныхКодов.Добавить("у45744");
// Проверяем вхождение текущего кода в этот массив
Если СписокНужныхКодов.Найти(СокрЛП(Товар.Код)) <> Неопределено И Продажа = Перечисления.ДаНет.Да Тогда
// Логика стала чище и понятнее
КонецЕсли;
Такой подход позволяет легко масштабировать код. Если завтра список кодов расширится до 20 позиций, вам не придется загромождать условие Если, достаточно будет просто добавить новые элементы в массив.
Использование конкретных кодов (например, "у45544") непосредственно в программном коде считается плохим тоном в разработке. Это называется «хардкод». Если пользователь в справочнике изменит код товара, ваша программа перестанет работать, и придется вызывать программиста для правки кода.
Как сделать правильно:
Справочники.Товары.Доставка.УчаствуетВРасчетеСкидки. Тогда условие превратится в красивое: Если Товар.УчаствуетВРасчетеСкидки И Продажа = ....Подводя итог нашему разбору, выделим основные правила написания условий в 1С:
И и ИЛИ. Помните: И всегда выполняется первым.Перечисления.Имя.Значение, избегая преобразования в Строка().СокрЛП() для защиты от невидимых пробелов.Соблюдение этих простых правил сделает ваш код надежным, быстрым и устойчивым к изменениям данных в базе.