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

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

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

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

Архитектурная модель управляемой формы

В управляемых формах 1С строго разделяются два понятия:

  1. Данные формы (Реквизиты формы): структуры, массивы, таблицы значений или прикладные объекты (Объект.ИмяТабличнойЧасти), хранящие значения.
  2. Элементы формы: визуальные элементы интерфейса (поля ввода, таблицы, кнопки), которые лишь отображают данные и связаны с реквизитами через свойство ПутьКДанным.

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

Пошаговый алгоритм добавления колонки

Рассмотрим подробнее каждый этап добавления колонок на серверной стороне формы (например, в обработчике ПриСозданииНаСервере).

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

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

Посмотрим на пример кода, в котором на основе списка скидок динамически формируются колонки таблицы для номенклатуры:


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

Важные ограничения и особенности работы

Проанализируем ключевые технические нюансы, с которыми сталкивается разработчик при динамическом изменении формы:

  1. Сохранение данных в базу: Реквизиты, добавленные с помощью ИзменитьРеквизиты, существуют исключительно в контексте формы в оперативной памяти. Платформа не записывает их в базу данных при стандартном сохранении объекта, поскольку они отсутствуют в метаданных конфигурации. Если эти данные необходимо сохранять, их следует вручную сериализовать (например, в регистр сведений или в строку хранилища) в обработчике ПередЗаписьюНаСервере.
  2. Производительность метода ИзменитьРеквизиты: Вызов этого метода перестраивает всю структуру формы и передает обновленный контекст. Категорически не рекомендуется вызывать ИзменитьРеквизиты внутри циклов. Все необходимые реквизиты нужно собирать в один общий массив и применять за один вызов.
  3. Перестроение колонок и удаление: Если состав колонок должен пересчитываться в процессе работы (например, при смене месяца в табеле), старые колонки обязательно нужно удалять. Метод ИзменитьРеквизиты принимает два параметра: массив добавляемых реквизитов и массив строковых имен удаляемых реквизитов. Связанные визуальные элементы формы необходимо перед этим удалять через Элементы.Удалить(...).
  4. Назначение обработчиков событий: Если для созданного поля ввода требуется реакция на действия пользователя (например, пересчет сумм), событие назначается программно с помощью метода УстановитьДействие:
    
    НовыйЭлемент.УстановитьДействие("ПриИзменении", "ДинамическаяКолонкаПриИзменении");
    
    Процедура-обработчик с директивой &НаКлиенте должна быть заранее описана в модуле формы.

Альтернативные подходы к реализации

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

  1. Реквизит формы типа «ТаблицаЗначений»: Вместо изменения прикладного реквизита Объект можно создать отдельный реквизит формы с типом ТаблицаЗначений. Все манипуляции с колонками и расчетными данными производятся в нем, а загрузка и выгрузка в объект выполняются явно в процедурах ПриЧтенииНаСервере и ПередЗаписьюНаСервере.
  2. Поле табличного документа: Для задач со сложным представлением данных (табели, графики, матричные отчеты) зачастую удобнее использовать элемент формы ПолеТабличногоДокумента. Табличный документ позволяет свободно объединять ячейки, менять форматирование и структуру строк и колонок без вызова ресурсоемкого метода ИзменитьРеквизиты.
← На главную