Как оптимизировать код для управления группой зависимых флажков в 1С?

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

В практике разработки на платформе 1С часто встречается задача, когда на форме расположено несколько флажков (реквизитов типа Булево), и логика программы требует, чтобы в один момент времени был включен только один из них. Типичная ошибка начинающего разработчика — создание огромных конструкций Если... ИначеЕсли, которые дублируют друг друга. Рассмотрим, как превратить «полотно» кода в элегантный и поддерживаемый алгоритм.

Проблема избыточного кода

Проанализируем исходную ситуацию. У нас есть 9 реквизитов: УГТ1, УГТ2 ... УГТ9. При изменении одного из них нужно сбросить остальные. Исходный код выглядит так:


&НаКлиенте
Процедура УстановитьЗначениеЗначка(Элемент)
    Если Элемент.Имя = "УГТ1" И Объект.УГТ1 Тогда
        Объект.УГТ2 = Ложь;
        Объект.УГТ3 = Ложь;
        // ... и так далее для всех 9 элементов
    ИначеЕсли Элемент.Имя = "УГТ2" И Объект.УГТ2 Тогда
        Объект.УГТ1 = Ложь;
        // ... повторение кода
    КонецЕсли;
КонецПроцедуры

Такой подход крайне неэффективен: его трудно читать, сложно масштабировать (если добавится 10-й флажок, придется переписывать всё), и в нем легко допустить опечатку. Разберем по шагам более качественные решения.

Решение №1: Использование цикла и динамического обращения к реквизитам

Самый простой и логичный шаг — использовать цикл. В 1С мы можем обращаться к свойствам объекта через квадратные скобки, передавая в них имя реквизита в виде строки. Выясним, как это сократит наш код.


&НаКлиенте
Процедура УстановитьЗначениеЗначка(Элемент)
    ИмяВыбранного = Элемент.Имя;
    
    // Если флажок сняли, ничего делать не нужно (или по логике задачи)
    Если Не Объект[ИмяВыбранного] Тогда
        Возврат;
    КонецЕсли;

    // Обходим все реквизиты с 1 по 9
    Для Номер = 1 По 9 Цикл
        ТекущееИмя = "УГТ" + Номер;
        
        // Пропускаем тот элемент, на который нажали
        Если ТекущееИмя = ИмяВыбранного Тогда
            Продолжить;
        КонецЕсли;
        
        // Сбрасываем остальные
        Объект[ТекущееИмя] = Ложь;
    КонецЦикла;
КонецПроцедуры

Преимущество: код стал короче в несколько раз. Теперь при добавлении новых элементов достаточно просто изменить верхнюю границу цикла.

Решение №2: Использование массива имен для универсальности

Рассмотрим ситуацию, когда имена реквизитов не имеют четкого цифрового окончания (например, ФлагСрочно, ФлагВажно, ФлагАрхив). В этом случае цикл по числам не подойдет. Разберем подход с использованием массива.


&НаКлиенте
Процедура УстановитьЗначениеЗначка(Элемент)
    Если Не Объект[Элемент.Имя] Тогда
        Возврат;
    КонецЕсли;

    МассивИмен = Новый Массив;
    МассивИмен.Добавить("УГТ1");
    МассивИмен.Добавить("УГТ2");
    // Добавляем все нужные имена...

    Для Каждого ИмяРеквизита Из МассивИмен Цикл
        Если ИмяРеквизита <> Элемент.Имя Тогда
            Объект[ИмяРеквизита] = Ложь;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Для еще большей оптимизации этот массив можно инициализировать один раз при создании формы и хранить в переменной модуля или реквизите формы, чтобы не создавать его заново при каждом клике.

Решение №3: Компактная логическая запись

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


&НаКлиенте
Процедура УстановитьЗначениеЗначка(Элемент)
    // Состояние каждого флажка зависит от того, является ли он "активным" в данный момент
    // Но это сработает, только если мы всегда хотим иметь один включенный флаг
    ВыбранноеИмя = Элемент.Имя;
    Значение = Объект[ВыбранноеИмя];
    
    Для Сч = 1 По 9 Цикл
        Имя = "УГТ" + Сч;
        Объект[Имя] = (Имя = ВыбранноеИмя) И Значение;
    КонецЦикла;
КонецПроцедуры

Здесь выражение (Имя = ВыбранноеИмя) возвращает Истина только для текущего элемента, а для остальных — Ложь. Это делает код предельно лаконичным.

Решение №4: Архитектурная оптимизация — «Поле переключателя»

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

  1. Создадим один реквизит ВариантУГТ (тип Число).
  2. Вынесем его на форму и установим вид Поле переключателя.
  3. В свойстве "Список выбора" заполним значения: 1 — "УГТ 1", 2 — "УГТ 2" и так далее.

Результат: платформа 1С автоматически будет управлять переключением. Вам вообще не придется писать программный код для сброса флажков. Это самый правильный путь с точки зрения производительности системы и чистоты кода.

Важные советы по оптимизации

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

← На главную