Как отобразить несколько источников данных и динамические колонки в одном табличном поле на обычных формах?

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

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

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

Анализ проблемы: почему колонки есть в отладчике, но не видны на форме

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

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

Способ 1. Быстрая привязка динамической Таблицы Значений через свойство «Данные» или «Значение»

Разберем базовый и наиболее универсальный способ, который позволяет переключать источники «на лету» без ручного описания каждого столбца. Если источником выступает произвольная ТаблицаЗначений (полученная выгрузкой табличной части или сформированная программно с добавлением новых колонок), ее можно напрямую передать в табличное поле.

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


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

В обычных формах также поддерживается прямая передача объекта в свойство Значение элемента управления. При таком подходе свойство Данные оставляется пустым, что исключает конфликт имен:


Процедура ПривязатьТаблицуНапрямую(ТЗДанные)
    
    // Сбрасываем старую привязку
    ЭлементыФормы.ТабличноеПоле1.Данные = "";
    
    // Устанавливаем таблицу как значение элемента
    ЭлементыФормы.ТабличноеПоле1.Значение = ТЗДанные;
    
    // Автоматически строим визуальные колонки
    ЭлементыФормы.ТабличноеПоле1.СоздатьКолонки();
    
КонецПроцедуры

Важный нюанс: если передаваемый параметр ТЧИсточник уже имеет тип ТаблицаЗначений, вызывать метод Выгрузить() не требуется — передаем коллекцию напрямую.

Способ 2. Точечное добавление и настройка колонок без полного пересоздания

Проанализируем ситуацию, когда вызов СоздатьКолонки() не подходит. Метод СоздатьКолонки() полностью сбрасывает ширину столбцов, заголовки, настроенный порядок и обработчики событий (например, ПриИзменении). Чтобы сохранить пользовательские настройки внешнего вида при добавлении динамических полей, выполним точечное создание колонок.

Разберем по шагам, как добавить динамическую колонку вручную:


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

Такой подход защищает интерфейс от мерцания и гарантирует сохранение всех назначенных ранее свойств элементов управления.

Ограничения и сохранение данных динамических колонок

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

Для долговременного сохранения динамических данных применяют два проверенных подхода:

  1. Использование служебной табличной части (EAV). В документе создается табличная часть со структурой НомерСтрокиИсточника, ИмяРеквизита и Значение. При открытии формы данные разворачиваются в плоскую таблицу значений с динамическими столбцами, а перед записью объекта сворачиваются обратно в служебную табличную часть.
  2. Сериализация в ХранилищеЗначения. Если по дополнительным колонкам не требуется строить отчеты или отборы на уровне СУБД, вся таблица значений перед сохранением помещается в реквизит документа с типом ХранилищеЗначения и восстанавливается при открытии формы.
← На главную