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

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

Особенности работы с динамическими таблицами на управляемых формах

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

Основные ошибки при программном изменении структуры таблицы

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

  1. Передача переменной объекта вместо имени реквизита: Метод ЗначениеВРеквизитФормы первым параметром принимает объект ТаблицаЗначений, а вторым — строковое имя реквизита формы (например, "ТЗ" или "Объект.ТабличнаяЧасть"), а не переменную с объектом таблицы.
  2. Отсутствие создания элементов формы: Вызов метода ИзменитьРеквизиты меняет только состав реквизитов контекста формы. Чтобы новые колонки отобразились на экране, необходимо программно добавить поля таблицы в коллекцию Элементы.
  3. Неопределенные типы колонок: При формировании объектов РеквизитФормы необходимо обязательно указывать типы данных (объект ОписаниеТипов). Если тип не задан или равен Неопределено, вызов ИзменитьРеквизиты приведет к ошибке.

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

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

Шаг 1. Очистка старых элементов и реквизитов

Если таблица обновляется динамически, сначала удаляем старые элементы колонок из родительской таблицы формы через Элементы.Удалить(), а затем формируем список удаляемых реквизитов контекста в формате ИмяРеквизитаТЗ.ИмяКолонки.

Шаг 2. Вызов метода ИзменитьРеквизиты

Формируем массив объектов РеквизитФормы и за один вызов метода ЭтаФорма.ИзменитьРеквизиты() обновляем структуру формы. Вызывать данный метод в цикле нельзя, так как это вызывает полную пересборку формы на сервере и снижает производительность.

Шаг 3. Загрузка данных и создание полей на форме

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

Пример программного кода

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


&НаСервере
Процедура СоздатьТаблицуЗначенийНаФормеСервер()

    // 1. Создаем исходную ТЗ с данными
    ТабРез = Новый ТаблицаЗначений;
    Для х = 1 По 5 Цикл
        ТабРез.Колонки.Добавить("Кол" + Формат(х, "ЧГ = 0"), Новый ОписаниеТипов("Строка"));
    КонецЦикла;

    Стр = ТабРез.Добавить();
    Стр.Кол1 = "Значение 1";
    Стр.Кол2 = "Значение 2";
    Стр.Кол3 = "Значение 3";
    Стр.Кол4 = "Значение 4";
    Стр.Кол5 = "Значение 5";

    ИмяРеквизитаТЗ = "ТЗ";
    ИмяЭлементаТаблицы = "ТаблицаФормы";

    // 2. Удаляем существующие элементы колонок на форме (если есть)
    ЭлементТаблица = Элементы[ИмяЭлементаТаблицы];
    МассивУдаляемыхЭлементов = Новый Массив;
    Для Каждого ТекЭлемент Из ЭлементТаблица.ПодчинённыеЭлементы Цикл
        МассивУдаляемыхЭлементов.Добавить(ТекЭлемент);
    КонецЦикла;
    Для Каждого ТекЭлемент Из МассивУдаляемыхЭлементов Цикл
        Элементы.Удалить(ТекЭлемент);
    КонецЦикла;

    // 3. Формируем списки добавляемых и удаляемых реквизитов формы
    МассивДобавляемыхРеквизитов = Новый Массив;
    МассивУдаляемыхРеквизитов = Новый Массив;

    // Получаем текущую структуру реквизитов формы
    МассивРеквизитов = ЭтаФорма.ПолучитьРеквизиты(ИмяРеквизитаТЗ);
    Для Каждого ТекРеквизит Из МассивРеквизитов Цикл
        МассивУдаляемыхРеквизитов.Добавить(ИмяРеквизитаТЗ + "." + ТекРеквизит.Имя);
    КонецЦикла;

    Для Каждого ТекКол Из ТабРез.Колонки Цикл
        МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(ТекКол.Имя, ТекКол.ТипЗначения, ИмяРеквизитаТЗ));
    КонецЦикла;

    // 4. Применяем изменения к структуре формы
    ЭтаФорма.ИзменитьРеквизиты(МассивДобавляемыхРеквизитов, МассивУдаляемыхРеквизитов);

    // 5. Заполняем реквизит формы данными (передаем имя реквизита строкой)
    ЗначениеВРеквизитФормы(ТабРез, ИмяРеквизитаТЗ);

    // 6. Программенно создаем визуальные элементы формы (колонки)
    Для Каждого ТекКол Из ТабРез.Колонки Цикл
        НовоеПоле = Элементы.Добавить(ИмяЭлементаТаблицы + ТекКол.Имя, Тип("ПолеФормы"), ЭлементТаблица);
        НовоеПоле.Вид = ВидПоляФормы.ПолеВвода;
        НовоеПоле.ПутьКДанным = ИмяРеквизитаТЗ + "." + ТекКол.Имя;
    КонецЦикла;

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

Альтернативный подход: управление видимостью статических колонок

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

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


Элементы.ТаблицаФормыКол1.Видимость = Ложь;
Элементы.ТаблицаФормыКол2.Видимость = Истина;

Этот подход работает быстрее и позволяет избежать повторного перестроения контекста формы на сервере.

← На главную