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