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

Программист IT и автоматизация бизнеса
← На главную

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

Почему метод Колонки.Добавить() не работает?

Разберем причину проблемы. На управляемой форме данные хранятся в специальном формате. Когда вы обращаетесь к Объект.ТЗ или просто к реквизиту формы типа «Таблица значений», вы работаете не с объектом ТаблицаЗначений, а с типом ДанныеФормыКоллекция.

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

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

Для того чтобы добавить новое поле в существующую таблицу, мы должны воспользоваться методом формы ИзменитьРеквизиты(). Этот метод позволяет добавить или удалить реквизиты «на лету».

Рассмотрим алгоритм действий:

  1. Создадим массив ДобавляемыеРеквизиты.
  2. Создадим объект РеквизитФормы, указав имя новой колонки, тип данных и путь к родительской таблице.
  3. Вызовем метод ИзменитьРеквизиты().

Посмотрим на пример кода:


&НаСервере
Процедура ДобавитьКолонкуНаСервере()
    // 1. Подготавливаем массив для новых реквизитов
    МассивДобавляемыхРеквизитов = Новый Массив;
    
    // Определяем тип данных для новой колонки (например, Строка длиной 100)
    ОписаниеТипаСтрока = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(100));
    
    // 2. Создаем описание реквизита
    // Параметры: Имя, Тип, ПутьКДанным (имя вашей ТЗ на форме), Заголовок
    НовыйРеквизит = Новый РеквизитФормы("ИмяНовойКолонки", ОписаниеТипаСтрока, "Объект.ТЗ", "Новая колонка", Истина);
    МассивДобавляемыхРеквизитов.Добавить(НовыйРеквизит);
    
    // 3. Фиксируем изменения в структуре формы
    ЭтаФорма.ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
КонецПроцедуры

Важный нюанс: Путь к данным в конструкторе РеквизитФормы указывается как строка. Если таблица является частью основного объекта обработки, пишем "Объект.ИмяТвое ТЗ". Если это просто реквизит формы — пишем "ИмяТвоейТЗ".

Шаг 2. Отображение колонки в интерфейсе

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

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

  1. Определяем родительский элемент (саму таблицу на форме).
  2. Добавляем новый элемент с типом ПолеФормы.
  3. Устанавливаем вид поля (например, поле ввода).
  4. Связываем поле с созданным ранее реквизитом через свойство ПутьКДанным.

&НаСервере
Процедура СоздатьЭлементИнтерфейса()
    // Находим саму таблицу на форме
    ТаблицаНаФорме = Элементы.ТЗ; 
    
    // Добавляем элемент "Поле" в эту таблицу
    НовоеПоле = Элементы.Добавить("ТЗ_ИмяНовойКолонки", Тип("ПолеФормы"), ТаблицаНаФорме);
    
    // Настраиваем свойства
    НовоеПоле.Вид = ВидПоляФормы.ПолеВвода;
    
    // Указываем путь к ранее созданному реквизиту
    НовоеПоле.ПутьКДанным = "Объект.ТЗ.ИмяНовойКолонки";
    НовоеПоле.Заголовок = "Добавленное поле";
КонецПроцедуры

Оптимизация и важные рекомендации

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

Рассмотрим несколько советов по оптимизации:

Полный пример комплексного решения

Объединим все шаги в одну универсальную процедуру, которую можно вызвать, например, при нажатии кнопки на форме:


&НаСервере
Процедура ДобавитьКолонкуПрограммно(ИмяКолонки, ЗаголовокКолонки)
    
    // 1. Работа с данными
    МассивДобавить = Новый Массив;
    МассивДобавить.Добавить(Новый РеквизитФормы(ИмяКолонки, Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)), "Объект.ТЗ", ЗаголовокКолонки));
    
    ЭтаФорма.ИзменитьРеквизиты(МассивДобавить);
    
    // 2. Работа с интерфейсом
    РодительТаблица = Элементы.ТЗ;
    НовыйЭлемент = Элементы.Добавить("ТЗ_" + ИмяКолонки, Тип("ПолеФормы"), РодительТаблица);
    НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
    НовыйЭлемент.ПутьКДанным = "Объект.ТЗ." + ИмяКолонки;
    
КонецПроцедуры

Таким образом, мы успешно обошли ограничение управляемых форм. Помните, что такие манипуляции возможны только на стороне сервера (&НаСервере), так как клиентская часть платформы не имеет прав на изменение метаданных формы в режиме реального времени.

← На главную