В управляемом приложении 1С разработчики нередко сталкиваются с ситуацией, когда при попытке программно изменить значение элемента формы (например, переключателя или тумблера) платформа выдает ошибку о невозможности присвоения значения. Разберем причинно-следственные связи этой ошибки, проанализируем архитектуру управляемых форм и рассмотрим правильные варианты решения данной задачи.
Проанализируем типичную ошибку. Разработчик пытается установить выбранный элемент тумблера следующим кодом:
&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьВидОперацииБыстрыйПереходПриОткрытии(Форма)
Объект = Форма.Объект;
Элементы = Форма.Элементы;
Если Объект.ВидОперации = ПредопределенноеЗначение("Перечисление.КВП_ВидыОперацийРегистрацииОплаты.Оплата1") Тогда
Элементы.ВидОперацииБыстрыйПереход = 0; // Ошибка!
ИначеЕсли Объект.ВидОперации = ПредопределенноеЗначение("Перечисление.КВП_ВидыОперацийРегистрацииОплаты.Оплата2") Тогда
Элементы.ВидОперацииБыстрыйПереход = 1; // Ошибка!
Иначе
Элементы.ВидОперацииБыстрыйПереход = 2; // Ошибка!
КонецЕсли;
КонецПроцедуры
При выполнении этого кода платформа 1С возвращает ошибку, сообщающую, что полю невозможно присвоить значение. Причина кроется в фундаментальном принципе разделения данных и интерфейса в управляемых формах 1С.
Коллекция Элементы отвечает исключительно за элементы пользовательского интерфейса (кнопки, поля ввода, переключатели) и их визуальные свойства: Видимость, Доступность, Заголовок и другие. Сам элемент формы не хранит в себе данные — он лишь отображает содержимое реквизита, привязанного к нему через свойство ПутьКДанным. Присваивать значение элементу напрямую через Элементы.ИмяЭлемента = Значение нельзя.
Для изменения значения, отображаемого на форме, нужно присваивать значение не визуальному элементу, а непосредственно реквизиту формы или реквизиту объекта.
Если вы передаете контекст формы в процедуру как параметр (например, Форма), обращаться к реквизиту формы следует через данный параметр:
Форма.ВидОперацииБыстрыйПереход = 0;
Если код выполняется непосредственно в модуле формы в контекстных процедурах (&НаСервере или &НаКлиенте), доступ к реквизиту формы осуществляется напрямую по его имени:
ВидОперацииБыстрыйПереход = 0;
Итоговый исправленный вариант процедуры выглядит следующим образом:
&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьВидОперацииБыстрыйПереходПриОткрытии(Форма)
Объект = Форма.Объект;
Если Объект.ВидОперации = ПредопределенноеЗначение("Перечисление.КВП_ВидыОперацийРегистрацииОплаты.Оплата1") Тогда
Форма.ВидОперацииБыстрыйПереход = 0;
ИначеЕсли Объект.ВидОперации = ПредопределенноеЗначение("Перечисление.КВП_ВидыОперацийРегистрацииОплаты.Оплата2") Тогда
Форма.ВидОперацииБыстрыйПереход = 1;
Иначе
Форма.ВидОперацииБыстрыйПереход = 2;
КонецЕсли;
КонецПроцедуры
Рассмотрим варианты оптимизации данной задачи, которые позволяют упростить код или полностью отказаться от ручного переписывания значений.
Создавать промежуточный числовой реквизит формы не обязательно. У элемента формы с видом Поле переключателя (в режиме отображения Тумблер) в свойстве ПутьКДанным можно указать непосредственно реквизит Объект.ВидОперации. В свойстве элемента СписокВыбора задаются сами значения перечисления. В таком случае платформа автоматически подсветит нужный тумблер при открытии без использования стороннего кода.
Если вам необходим отдельный реквизит формы, задайте ему тип соответствующего перечисления (ПеречислениеСсылка.КВП_ВидыОперацийРегистрацииОплаты), а не Число. Тогда инициализация в коде упростится до одной строки:
ВидОперацииБыстрыйПереход = Объект.ВидОперации;
Установку начальных значений реквизитов формы и заполнение списка выбора рекомендуется выполнять на сервере в обработчике ПриСозданииНаСервере. Выполнение этих действий на клиенте в ПриОткрытии приводит к лишним вызовам и замедляет работу интерфейса.
Важно помнить: Переключатель (тумблер) подсвечивает активную кнопку только при полном совпадении типа и значения реквизита с одним из элементов в коллекции СписокВыбора. Если типу реквизита присвоить значение, отсутствующее в списке выбора, тумблер визуально сбросит выбор и останется без выделенной кнопки.