При разработке сложных интерфейсов и динамических отборов в управляемом приложении 1С часто возникает задача создания элементов формы «на лету» во время работы пользователя. При этом начинающие разработчики сталкиваются с вопросом: как именно передать или изменить значение в таком программно сформированном поле ввода.
Разберем архитектурные особенности управляемых форм, пошаговый алгоритм создания реквизитов и элементов, а также правильный синтаксис для записи данных.
В управляемых формах 1С элементы интерфейса (поля ввода, флажки, переключатели) не хранят данные самостоятельно. Они являются исключительно визуальным представлением данных, находящихся в реквизитах формы. Связь между визуальным элементом и данными задается с помощью свойства ПутьКДанным.
Следовательно, для программного вывода поля со значением необходимо выполнить два обязательных действия:
ИзменитьРеквизиты.ПутьКДанным с реквизитом и записать значение в созданный реквизит.Рассмотрим серверную процедуру, которая создает реквизит строкового типа, связывает с ним поле ввода на форме и сразу устанавливает начальное значение.
&НаСервере
Процедура ДобавитьПолеВводаНаСервере(ИмяСуффикса, НачальноеЗначение)
ИмяРеквизита = "РеквизитКомментарий" + ИмяСуффикса;
ИмяЭлемента = "ПолеКомментарий" + ИмяСуффикса;
// 1. Формируем массив новых реквизитов формы
ДобавляемыеРеквизиты = Новый Массив;
НовыйРеквизит = Новый РеквизитФормы(ИмяРеквизита, Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(150)));
ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);
// 2. Применяем изменения к структуре формы
ИзменитьРеквизиты(ДобавляемыеРеквизиты);
// 3. Создаем визуальный элемент на форме
НовыйЭлемент = ЭтаФорма.Элементы.Добавить(ИмяЭлемента, Тип("ПолеФормы"), ЭтаФорма.Элементы.Группа1);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = ИмяРеквизита;
НовыйЭлемент.Заголовок = "Комментарий " + ИмяСуффикса;
// 4. Записываем значение в динамически созданный реквизит
ЭтаФорма[ИмяРеквизита] = НачальноеЗначение;
КонецПроцедуры
После вызова метода ИзменитьРеквизиты созданный реквизит становится полноправным свойством формы. Так как его имя формируется динамически во время выполнения программы, прямое обращение через точку невозможно. Обращение выполняется через оператор квадратных скобок по строковому имени реквизита:
// На сервере
ЭтаФорма["Список" + ИмяСтраницы] = "Текст для серверной процедуры";
// На клиенте
ЭтаФорма["Список" + ИмяСтраницы] = "Текст, измененный на клиенте";
Такой синтаксис позволяет как считывать текущие введенные пользователем данные, так и перезаписывать их из любого контекста модуля формы.
Если требуется отслеживать действия пользователя в созданном поле ввода (например, изменение значения), необходимо привязать обработчик через метод УстановитьДействие.
&НаСервере
Процедура НазначитьСобытиеЭлементу(ИмяЭлемента)
ЭлементФормы = ЭтаФорма.Элементы[ИмяЭлемента];
ЭлементФормы.УстановитьДействие("ПриИзменении", "ДинамическоеПолеПриИзменении");
КонецПроцедуры
&НаКлиенте
Процедура ДинамическоеПолеПриИзменении(Элемент)
// Обработка изменения данных пользователем
ТекущееЗначение = ЭтаФорма[Элемент.ПутьКДанным];
ПоказатьОповещениеПользователя("Изменено значение", , ТекущееЗначение);
КонецПроцедуры
Обратите внимание: процедура-обработчик должна быть заранее объявлена в модуле формы с соответствующей директивой компиляции (обычно &НаКлиенте).
ИзменитьРеквизиты приводит к полной переинициализации контекста формы и передаче данных между клиентом и сервером. Если необходимо добавить несколько полей, накапливайте все объекты РеквизитФормы в один массив и вызывайте ИзменитьРеквизиты один раз, а не в цикле.ПолучитьРеквизиты().Элементы.Удалить(...) (или очистить его свойство ПутьКДанным), и только затем вызывать ИзменитьРеквизиты с массивом удаляемых имен во втором параметре.