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

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

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

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

Ошибки прямого обращения к элементам формы

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

Посмотрим на пример правильного добавления новой вкладки на панель с именем ПанельМаршрутов:


// Добавление новой страницы: первый параметр — системное имя, второй — заголовок вкладки
ЭлементыФормы.ПанельМаршрутов.Страницы.Добавить("Вкладка_" + КодМаршрута, "Маршрут № " + СокрЛП(НаименованиеМаршрута));

// Активация созданной страницы для последующего добавления элементов
ЭлементыФормы.ПанельМаршрутов.ТекущаяСтраница = ЭлементыФормы.ПанельМаршрутов.Страницы["Вкладка_" + КодМаршрута];

Программное добавление табличного поля и настройка привязок

После создания страницы необходимо динамически добавить элемент управления, на котором будут отображаться данные. Для этого используется метод ЭлементыФормы.Добавить() с указанием родительской панели.

Важное правило именования элементов: имя создаваемого элемента управления должно начинаться с буквы или знака подчеркивания и не содержать пробелов и специальных символов. Если использовать чистый код (например, "0000003"), платформа выдаст исключение: «Неверное имя! Имя должно состоять из одного слова, начинаться с буквы...». Поэтому к числовым кодам всегда следует добавлять строковый префикс, например: "ТП_" + КодМаршрута.

Разберем по шагам создание табличного поля с позиционированием и автоматическим растягиванием:


Для Каждого СтрокаТЗ Из ТаблицаМаршрутов Цикл

    ИмяСтраницы = "Страница_" + СокрЛП(СтрокаТЗ.Код);
    ИмяТаблицы  = "ТП_" + СокрЛП(СтрокаТЗ.Код);

    // 1. Создаем страницу
    ЭлементыФормы.Панель.Страницы.Добавить(ИмяСтраницы, Строка(СтрокаТЗ.Маршрут));
    ЭлементыФормы.Панель.ТекущаяСтраница = ЭлементыФормы.Панель.Страницы[ИмяСтраницы];

    // 2. Добавляем элемент управления ТабличноеПоле на панель
    ТПНаФорме = ЭлементыФормы.Добавить(Тип("ТабличноеПоле"), ИмяТаблицы, Истина, ЭлементыФормы.Панель);
    
    // 3. Устанавливаем геометрические размеры и видимость
    ТПНаФорме.Верх = 4;
    ТПНаФорме.Лево = 4;
    ТПНаФорме.Высота = ЭлементыФормы.Панель.Высота - 20;
    ТПНаФорме.Ширина = ЭлементыФормы.Панель.Ширина - 20;
    ТПНаФорме.Доступность = Истина;
    ТПНаФорме.ТолькоПросмотр = Ложь;

    // 4. Привязываем границы элемента к границам родительской панели
    ТПНаФорме.УстановитьПривязку(ГраницаЭлементаУправления.Низ, ЭлементыФормы.Панель, ГраницаЭлементаУправления.Низ);
    ТПНаФорме.УстановитьПривязку(ГраницаЭлементаУправления.Право, ЭлементыФормы.Панель, ГраницаЭлементаУправления.Право);

КонецЦикла;

Заполнение данными и генерация колонок

Созданное табличное поле изначально не содержит структуры колонок. Чтобы отобразить данные:

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

Если в таблице необходимо вывести числовые итоги в подвале, включаем отображение подвала и настраиваем текст для соответствующих колонок:


ТПНаФорме.Подвал = Истина;
КолонкаСумма = ТПНаФорме.Колонки.Найти("Сумма");
Если КолонкаСумма <> Неопределено Тогда
    КолонкаСумма.ТекстПодвала = Формат(ТЗМаршрута.Итог("Сумма"), "ЧДЦ=2");
    КолонкаСумма.ГоризонтальноеПоложениеВПодвале = ПоложениеТекстаЭлементаУправления.Право;
КонецЕсли;

Подключение универсального обработчика событий

Рассмотрим, как назначить события (например, активизацию строки или ячейки) для динамически созданных таблиц. В 1С для обычных форм используется метод УстановитьДействие.

Проанализируем пример подключения общего обработчика события ПриАктивизацииЯчейки:


// Подключение действия к динамическому элементу
ТПНаФорме.УстановитьДействие("ПриАктивизацииЯчейки", "ТабличноеПолеПриАктивизацииЯчейки");

В модуле формы объявляем процедуру-обработчик. Параметр Элемент передает ссылку на конкретный элемент управления, в котором произошло событие, что позволяет использовать одну процедуру для всех динамических таблиц:


Процедура ТабличноеПолеПриАктивизацииЯчейки(Элемент)
    
    // Получаем текущую строку и имя активного элемента
    ТекущиеДанные = Элемент.ТекущиеДанные;
    ИмяЭлемента   = Элемент.Имя;
    
    Если ТекущиеДанные <> Неопределено Тогда
        // Обработка логики при выборе ячейки
    КонецЕсли;
    
КонецПроцедуры

Очистка динамических элементов при повторном формировании

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


// Удаляем созданные табличные поля
Для Каждого ТекСтраница Из ЭлементыФормы.Панель.Страницы Цикл
    ИмяТП = "ТП_" + ТекСтраница.Имя;
    ЭлементТП = ЭлементыФормы.Найти(ИмяТП);
    Если ЭлементТП <> Неопределено Тогда
        ЭлементыФормы.Удалить(ЭлементТП);
    КонецЕсли;
КонецЦикла;

// Очищаем коллекцию страниц панели
ЭлементыФормы.Панель.Страницы.Очистить();

Альтернативные архитектурные решения

Динамическое создание десятков страниц и таблиц может приводить к повышенному потреблению памяти и замедлению прорисовки формы. Если данных много, рекомендуется использовать альтернативные варианты:

  1. Схема Master-Detail: на форме размещаются две статические таблицы. Слева — список маршрутов, справа — документы. В событии ПриАктивизацииСтроки левой таблицы правая часть динамически фильтруется или перезаполняется данными выбранного маршрута.
  2. Дерево значений: все данные выводятся в одно табличное поле с типом «Дерево значений», где верхний уровень группировки — маршруты с итогами, а вложенный — строки документов.
  3. Поле табличного документа: вывод отчета со встроенными группировками и итогами с помощью макета.
← На главную