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