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

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

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

Постановка задачи и выбор стратегии решения

Рассмотрим ситуацию: у нас есть основная табличная часть документа, где перечисляются технологические операции. Нам необходимо, чтобы при открытии документа в этой таблице появлялись дополнительные колонки, соответствующие списку продукции из другой табличной части этого же документа. Важно понимать различие между Объектом (данными в базе) и Формой (визуальным представлением). Мы будем добавлять колонки именно на форму, связывая их с динамически созданными реквизитами.

Алгоритм решения задачи состоит из следующих этапов:

  1. Определение списка необходимых колонок (например, через запрос к данным документа).
  2. Программное создание реквизитов формы с помощью метода ИзменитьРеквизиты.
  3. Программное создание элементов формы (полей ввода) и их привязка к созданным реквизитам.
  4. Организация загрузки и сохранения данных в дополнительные структуры (например, в регистр сведений).

Шаг 1: Формирование списка реквизитов

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

Рассмотрим пример кода для подготовки массива реквизитов:


МассивРеквизитов = Новый Массив;
// Подготовим описание типов для будущих колонок (например, Число)
КвалификаторЧисла = Новый КвалификаторыЧисла(15, 3, ДопустимыйЗнак.Неотрицательный);
ОписаниеТипаЧисло = Новый ОписаниеТипов("Число", КвалификаторЧисла);

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ЗаказПродукция.НомерСтроки КАК Номер,
    |	ЗаказПродукция.Продукция.Наименование КАК Наименование
    |ИЗ
    |	Документ.Заказ.Продукция КАК ЗаказПродукция
    |ГДЕ
    |	ЗаказПродукция.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    // Формируем программное имя без спецсимволов
    ИмяРеквизита = "Прод_" + СтрЗаменить(Выборка.Номер, " ", "_");
    Синоним = Выборка.Наименование;
    
    // Добавляем описание реквизита в массив. 
    // Третий параметр - это путь к данным (наша ТЧ "Монтажи")
    НовыйРеквизит = Новый РеквизитФормы(ИмяРеквизита, ОписаниеТипаЧисло, "Объект.Монтажи", Синоним, Ложь);
    МассивРеквизитов.Добавить(НовыйРеквизит);
КонецЦикла;

Шаг 2: Использование метода ИзменитьРеквизиты

Метод ИзменитьРеквизиты является ключевым. Он позволяет за одно обращение к серверу добавить новые реквизиты в структуру формы или удалить старые. Разберем нюанс: если мы вызываем этот код при каждом открытии или обновлении, нам нужно сначала удалить колонки, созданные ранее, чтобы избежать ошибки дублирования имен.

Проанализируем процесс изменения состава реквизитов:


// Перед добавлением желательно собрать имена старых динамических реквизитов в МассивДляУдаления
// ИзменитьРеквизиты(МассивДобавляемыхРеквизитов, МассивУдаляемыхРеквизитов);
ИзменитьРеквизиты(МассивРеквизитов);

Важно: Метод ИзменитьРеквизиты — это ресурсоемкая операция. Старайтесь собирать все изменения в один массив и вызывать метод один раз, а не внутри цикла.

Шаг 3: Визуализация — создание элементов формы

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

Рассмотрим по шагам добавление визуальных элементов:


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

Типичные ошибки и способы их решения

При реализации динамических колонок программисты часто сталкиваются с ошибкой «Недопустимое значение параметров» при вызове Элементы.Добавить. Выясним основные причины этой ситуации:

Работа с данными: сохранение и чтение

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

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

Пример заполнения данных при открытии:


// Пример упрощенной логики заполнения
Для Каждого СтрокаТЧ Из Объект.Монтажи Цикл
    // Получаем данные из регистра для данной строки и заполняем динамические колонки
    // СтрокаТЧ["ИмяДинамическойКолонки"] = ЗначениеИзРегистра;
КонецЦикла;

Оптимизация производительности

Проанализируем ситуацию, когда продукции очень много (например, 50-100 наименований). Огромное количество колонок сделает форму «тяжелой» и неудобной для пользователя. В таких случаях рекомендуется:

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

← На главную