Как программно создать таблицу на форме и работать с её динамическими колонками

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

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

Создание структуры данных и визуального элемента

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

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


// 1. Формируем массив добавляемых реквизитов
МассивДобавляемыхРеквизитов = Новый Массив;
ИмяРеквизита = "Таб" + ИмяДляЭлемента;

// Создаем описание типа для таблицы
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("ТаблицаЗначений"));
ОписаниеТиповТЗ = Новый ОписаниеТипов(МассивТипов);

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

// 2. Добавляем колонки в этот реквизит (указываем путь к владельцу)
// Допустим, нам нужно добавить колонку "Количество"
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы("Количество", Новый ОписаниеТипов("Число"), ИмяРеквизита));

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

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

Назначение общего обработчика события

Когда таблиц много, создавать под каждую отдельную процедуру в модуле невозможно. Мы воспользуемся методом УстановитьДействие, чтобы назначить всем созданным таблицам одну и ту же процедуру-обработчик. Это позволяет централизованно обрабатывать изменения во всех динамических объектах.

Рассмотрим, как это реализовать:


// Создание визуального элемента
Таб = Элементы.Добавить("Таб" + ИмяДляЭлемента, Тип("ТаблицаФормы"), ГруппаДляРазмещения);
Таб.ПутьКДанным = "Таб" + ИмяДляЭлемента;

// Подвязываем действие "ПриИзменении"
Таб.УстановитьДействие("ПриИзменении", "ПриИзмененииТаблицы");

Теперь выясним, как должна выглядеть сама процедура ПриИзмененииТаблицы. Поскольку обработчик общий, нам нужно понимать, какая именно таблица его вызвала. Для этого используется параметр Элемент, который автоматически передается платформой.


&НаКлиенте
Процедура ПриИзмененииТаблицы(Элемент)
    
    // Получаем имя таблицы, которая вызвала событие
    ИмяТаблицы = Элемент.Имя;
    
    // Получаем текущую строку этой таблицы
    ТекущиеДанные = Элементы[ИмяТаблицы].ТекущиеДанные;
    
    Если ТекущиеДанные <> Неопределено Тогда
        // Здесь мы можем выполнять логику обработки
        Сообщить("Изменена таблица: " + ИмяТаблицы);
    КонецЕсли;
    
КонецПроцедуры

Работа с динамическими именами колонок

Самый частый вопрос при программной работе с таблицами: «Как обратиться к колонке, если её имя генерируется динамически (например, Колонка_Дом_Шкаф)?»

В 1С привычное обращение через точку (ТекущиеДанные.ИмяКолонки) работает только тогда, когда имя известно на этапе написания кода. Если же имя колонки лежит в переменной, такой синтаксис вызовет ошибку. Решением является использование оператора квадратные скобки [].

Проанализируем ситуацию: у нас есть переменная ИмяДинамическойКолонки, и нам нужно записать туда значение. Рассмотрим правильный подход:


// Допустим, мы создали колонку с составным именем
Часть1 = "Дом";
Часть2 = "Шкаф";
ИмяКолонки = "Колонка" + Часть1 + Часть2;

// Добавляем новую строку в таблицу
НоваяСтрока = ЭтаФорма["Таб" + ИмяДляЭлемента].Добавить();

// ПРАВИЛЬНОЕ ОБРАЩЕНИЕ:
НоваяСтрока[ИмяКолонки] = "Значение для шкафа";

// Если нужно получить значение, используем тот же принцип:
Значение = НоваяСтрока[ИмяКолонки];

Этот метод универсален. Он работает как для строк ТаблицыЗначений на сервере, так и для ДанныеФормыКоллекция на клиенте. Использование квадратных скобок позволяет вычислять имя колонки в реальном времени, что критически важно при создании сложных динамических интерфейсов.

Рекомендации по управлению динамическими объектами

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

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

Таким образом, сочетание методов ИзменитьРеквизиты, УстановитьДействие и использование квадратных скобок [] для доступа к полям предоставляет разработчику мощный инструмент для создания гибких и адаптивных интерфейсов в системе 1С:Предприятие.

← На главную