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

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

В процессе разработки на платформе 1С часто возникает задача динамически отображать данные в удобном табличном виде. Стандартный элемент ТабличныйДокумент идеально для этого подходит. Однако, что делать, если количество таких табличных документов заранее неизвестно и их нужно создавать по определенному условию или действию пользователя? В этой статье мы подробно разберем, как программно создать не только сам элемент для отображения, но и связанный с ним реквизит данных на управляемой форме.

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

Решение 1: Полное динамическое создание реквизита и элемента

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

  1. Создание нового реквизита формы типа ТабличныйДокумент.
  2. Создание нового элемента формы типа ПолеФормы и его привязка к созданному реквизиту.

Разберем каждый шаг подробнее.

Шаг 1. Программное добавление реквизита формы

Для изменения состава реквизитов управляемой формы существует специальный системный метод ИзменитьРеквизиты() — для этого подойдёт инструментарий разработчика с консолями кода и запросов. Он принимает в качестве параметра массив новых реквизитов. Важно помнить, что это единственный легальный способ добавить реквизит на форму "на лету".

Для этого подготовим массив, создадим объект Новый РеквизитФормы, указав его имя и тип, и вызовем процедуру изменения.


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

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

После выполнения этого кода в составе реквизитов формы (объект, доступный через ЭтотОбъект) появится новый реквизит с именем МойТабличныйДокументДанные. Однако на самой форме мы его пока не увидим, так как для него не создан визуальный элемент.

Шаг 2. Создание визуального элемента и его привязка к данным

Теперь, когда у нас есть "хранилище" для данных, создадим элемент, который будет его отображать. Для отладки свойств созданных элементов удобно применять редактор форм в режиме предприятия. Для этого используется метод Элементы.Добавить().

Ключевыми параметрами здесь являются:

После создания элемента необходимо настроить два его важнейших свойства:

Дополним наш предыдущий пример кодом для создания элемента:


&НаСервере
Процедура СоздатьТабличныйДокументНаСервере()
    
    // ... код создания реквизита из Шага 1 ...
    МассивНовыхРеквизитов = Новый Массив;
    НовыйРеквизит = Новый РеквизитФормы("МойТабличныйДокументДанные", Новый ОписаниеТипов("ТабличныйДокумент"));
    МассивНовыхРеквизитов.Добавить(НовыйРеквизит);
    ИзменитьРеквизиты(МассивНовыхРеквизитов);
    
    // --- Шаг 2: Создание элемента ---
    
    // "ЭлементТабДок" - имя визуального элемента.
    // Элементы.ГруппаДляТаблиц - предполагается, что на форме есть группа с таким именем.
    НовыйЭлемент = Элементы.Добавить("ЭлементТабДок", Тип("ПолеФормы"), Элементы.ГруппаДляТаблиц);
    
    // Настраиваем вид поля.
    НовыйЭлемент.Вид = ВидПоляФормы.ПолеТабличногоДокумента;
    
    // Устанавливаем связь с данными.
    НовыйЭлемент.ПутьКДанным = "МойТабличныйДокументДанные";

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

Шаг 3. Заполнение данными

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


&НаСервере
Процедура ЗаполнитьТаблицуДанными()

    // Обращаемся к реквизиту напрямую по имени или через ЭтотОбъект
    ТабДок = ЭтотОбъект.МойТабличныйДокументДанные;
    ТабДок.Очистить();
    
    // Выводим данные
    Область = ТабДок.ПолучитьОбласть("R1C1");
    Область.Текст = "Это наша динамическая таблица!";
    
    Область = ТабДок.ПолучитьОбласть("R2C1:R2C2");
    Область.Текст = "Объединенная ячейка";
    Область.Объединить();

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

Создание нескольких табличных документов в цикле

Рассмотренный выше подход легко масштабируется для создания нескольких элементов. Главное правило — имена реквизитов и элементов должны быть уникальными. Для этого их можно генерировать в цикле, добавляя к базовому имени номер итерации.

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

Посмотрим на пример создания трех таблиц:


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

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

Решение 2: Альтернативный подход с использованием одного статического элемента

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

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

Алгоритм действий в этом случае предельно прост:

  1. В режиме конфигуратора добавьте на форму реквизит (например, ТаблицаОтчета) с типом ТабличныйДокумент.
  2. В режиме конфигуратора перетащите этот реквизит на форму, чтобы создался связанный с ним элемент.
  3. В коде просто обращайтесь к этому реквизиту, очищайте его и заполняйте новыми данными.

Пример кода для такого сценария:


&НаСервере
Процедура ОбновитьСодержимоеОтчета()

    // "ТаблицаОтчета" - имя реквизита, созданного в конфигураторе
    ТабДок = ЭтотОбъект.ТаблицаОтчета;
    
    // Очищаем старые данные
    ТабДок.Очистить();
    
    // Формируем и выводим новые данные
    ТабДок.ПолучитьОбласть("A1").Текст = "Новые данные, сформированные в " + ТекущаяДата();
    // ... дальнейшее заполнение ...

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

Преимущества этого метода:

Недостаток:

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

← На главную