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

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

В практике разработки на платформе 1С часто возникает задача отображения данных, структура которых заранее неизвестна. Например, это может быть матрица показателей, отчет с динамическим количеством колонок или кросс-таблица. Обычного добавления реквизита типа ТаблицаЗначений в дерево реквизитов формы в конфигураторе часто недостаточно, особенно если состав колонок должен меняться «на лету». Рассмотрим подробно, как правильно реализовать этот механизм, разберем типичные ошибки и проанализируем работающий код.

Почему таблица не отображается на форме сразу

Разберем ситуацию: вы создали реквизит формы с типом ТаблицаЗначений, но при запуске приложения видите пустое место. Выясним причину этого поведения. В управляемых формах 1С существует жесткое разделение между данными (реквизитами) и отображением (элементами формы). Чтобы таблица стала видимой и функциональной, необходимо пройти три этапа:

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

Шаг 1. Программное создание реквизитов данных

Для того чтобы в объекте ДанныеФормыКоллекция появились колонки, мы должны использовать метод ИзменитьРеквизиты. Важно помнить, что этот метод работает на сервере и требует массива описаний реквизитов. Проанализируем пример кода, который создает структуру колонок:


&НаСервере
Процедура СоздатьСтруктуруТаблицыНаСервере()
    
    МассивДобавляемыхРеквизитов = Новый Массив;
    ИмяРеквизитаТЗ = "врТЗХранилище";
    
    // Создаем описание колонок (например, 30 штук)
    Для н = 0 По 29 Цикл
        ИмяКолонки = "Код" + Формат(н, "ЧГ=0");
        
        // Обязательно указываем путь к родительскому реквизиту
        НовыйРеквизит = Новый РеквизитФормы(ИмяКолонки, Новый ОписаниеТипов("Строка"), ИмяРеквизитаТЗ, "Заголовок " + н);
        МассивДобавляемыхРеквизитов.Добавить(НовыйРеквизит);
    КонецЦикла;
    
    // Вызываем изменение реквизитов ОДИН РАЗ вне цикла для повышения производительности
    ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
    
КонецПроцедуры

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

Шаг 2. Программное создание элементов формы

Теперь, когда в памяти сервера структура данных подготовлена, нам нужно «нарисовать» её для пользователя. Рассмотрим, как программно добавить саму таблицу и её колонки. Мы будем использовать коллекцию Элементы.


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

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

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

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


&НаСервере
Процедура ЗаполнитьДанныеТаблицы()
    
    // Получаем объект ТаблицаЗначений из реквизита формы
    ТЗОбъект = РеквизитФормыВЗначение("врТЗХранилище", Тип("ТаблицаЗначений"));
    
    // Очищаем и заполняем
    ТЗОбъект.Очистить();
    Для и = 1 По 10 Цикл
        НоваяСтрока = ТЗОбъект.Добавить();
        Для Каждого Колонка Из ТЗОбъект.Колонки Цикл
            НоваяСтрока[Колонка.Имя] = "Данные " + и;
        КонецЦикла;
    КонецЦикла;
    
    // Загружаем данные обратно в реквизит формы
    ЗначениеВДанныеФормы(ТЗОбъект, врТЗХранилище);
    
КонецПроцедуры

Типичные ошибки и рекомендации по оптимизации

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

  1. Очистка при повторном вызове: Если ваша процедура вызывается несколько раз (например, по кнопке «Обновить»), код упадет с ошибкой «Элемент с таким именем уже существует». Перед добавлением новых реквизитов и элементов необходимо программно удалять старые. Используйте Элементы.Удалить() для визуальных частей и второй параметр метода ИзменитьРеквизиты для удаления данных.
  2. Квалификаторы типов: При создании ОписаниеТипов для чисел или дат всегда указывайте квалификаторы (точность, разрядность). Без этого поля ввода в таблице могут вести себя некорректно.
  3. Фиксация колонок: Если у вас много динамических колонок, пользователю будет неудобно прокручивать таблицу. Используйте свойство ЭлементТаблица.ФиксацияСлева, чтобы закрепить ключевые поля (например, наименование номенклатуры).
  4. Работа напрямую с ДанныеФормыКоллекция: Если структура колонок уже определена и вам нужно просто добавить строки, не обязательно использовать РеквизитФормыВЗначение. Можно работать напрямую с реквизитом врТЗХранилище, используя метод .Добавить(). Это работает быстрее, так как исключает тяжелую операцию конвертации данных.

Таким образом, мы разобрали полный цикл работы с динамической таблицей. Главный секрет успеха в управляемых формах — это четкое понимание того, что Реквизит (данные) и Элемент (визуал) создаются отдельно и связываются через свойство ПутьКДанным.

← На главную