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