Как программно создать страницы (вкладки) и таблицы на управляемой форме в 1С 8.3?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке сложных интерфейсов на управляемых формах 1С часто возникает задача динамического формирования элементов: нужно создать произвольное количество вкладок (страниц) и разместить на каждой из них свою таблицу или динамический список. В процессе реализации разработчики нередко сталкиваются с ошибкой «Недопустимое значение параметров» при вызове метода Элементы.Добавить().

В этой статье мы подробно проанализируем причины возникновения данной ошибки, разберем корректную последовательность программного создания реквизитов и элементов формы, а также рассмотрим архитектурный подход, позволяющий избежать лишней нагрузки на сервер.

Выясним причину ошибки «Недопустимое значение параметров»

Рассмотрим ситуацию, когда при выполнении следующего кода система выдает ошибку:


эТаблица = Элементы.Добавить(ИмяТаблицы, Тип("ТаблицаФормы"), Элементы.КучаСтраниц);

Ошибка «Недопустимое значение параметров» в данном вызове возникает по двум основным причинам:

  1. Неверная иерархия элементов формы: В качестве третьего параметра (родителя) передается элемент Элементы.КучаСтраниц, имеющий вид ВидГруппыФормы.Страницы (контейнер вкладок). Платформа 1С не позволяет вкладывать элемент ТаблицаФормы напрямую в панель страниц. Вложенным элементом панели страниц может быть только группа с видом ВидГруппыФормы.Страница. И уже внутри этой конкретной страницы должна располагаться таблица.
  2. Конфликт имен элементов: Первый параметр метода Элементы.Добавить() задает имя создаваемого элемента. Имя должно быть строго уникальным в рамках всей формы. Если на форме уже существует элемент или реквизит с таким же именем (или имя передано пустой строкой), платформа вернет ошибку параметров.

Правильный алгоритм программного создания вкладок и таблиц

Разберем по шагам корректный порядок действий для динамического создания вкладок и подчиненных таблиц формы.

  1. Сначала создаем страницу-контейнер внутри группы страниц с видом ВидГруппыФормы.Страница.
  2. Затем добавляем ТаблицаФормы, указывая в качестве родителя именно созданную страницу.
  3. Назначаем свойство ПутьКДанным для созданной таблицы.
  4. Создаем колонки таблицы (элементы с типом ПолеФормы), связывая их путь к данным с реквизитами таблицы.

Посмотрим на пример кода, реализующий создание динамического реквизита и элементов формы:


&НаСервере
Процедура СоздатьСтраницуИТаблицуНаСервере(ИмяСтраницы, ЗаголовокСтраницы, ИмяТЗ)

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

КонецПроцедуры

Оптимальный подход: «Одна таблица — много вкладок»

Программирование множества реквизитов типа ТаблицаЗначений или ДинамическийСписок на каждой вкладке создает существенную нагрузку на сервер 1С и СУБД, так как каждый динамический список генерирует свои отдельные запросы к базе данных.

В большинстве практических задач (например, отображение справочника с разбивкой по видам или категориям) эффективнее использовать схему с **одной таблицей** и программной сменой отбора:

  1. На форме статически создается один реквизит Список (тип ДинамическийСписок) и одна ТаблицаФормы.
  2. Программно при открытии формы создаются только вкладки (элементы ГруппаФормы с видом ВидГруппыФормы.Страница).
  3. Назначается обработчик события панели страниц ПриСменеТекущейСтраницы.
  4. В момент переключения вкладки пользователем программно меняется отбор в существующем динамическом списке с помощью Список.КомпоновщикНастроек.Настройки.Отбор.

Проанализируем пример кода установки отбора при смене вкладки:


&НаКлиенте
Процедура КучаСтраницПриСменеТекущейСтраницы(Элемент, ТекущаяСтраница)
    
    // Получаем значение фильтра, привязанное к имени страницы
    ВидНоменклатуры = ПолучитьВидПоИмениСтраницы(ТекущаяСтраница.Имя);
    УстановитьОтборСпискаНаСервере(ВидНоменклатуры);
    
КонецПроцедуры

&НаСервере
Процедура УстановитьОтборСпискаНаСервере(ВидНоменклатуры)
    
    ЭлементОтбора = Неопределено;
    ПолеОтбора = Новый ПолеКомпоновкиДанных("ВидНоменклатуры");
    
    // Ищем существующий отбор или создаем новый
    Для Каждого ЭлементИзОтбора Из Список.КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл
        Если ЭлементИзОтбора.ЛевоеЗначение = ПолеОтбора Тогда
            ЭлементОтбора = ЭлементИзОтбора;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    Если ЭлементОтбора = Неопределено Тогда
        ЭлементОтбора = Список.КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
        ЭлементОтбора.ЛевоеЗначение = ПолеОтбора;
    КонецЕсли;
    
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементОтбора.ПравоеЗначение = ВидНоменклатуры;
    ЭлементОтбора.Использование = ЗначениеЗаполнено(ВидНоменклатуры);
    
КонецПроцедуры

Такой подход обеспечивает высокую скорость работы формы, исключает ошибки недопустимых параметров при построении сложных составных элементов и упрощает дальнейшее обслуживание кода.

← На главную