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

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

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

Ключевой принцип: разделение данных и отображения

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

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

Шаг 1: Подготовка структуры данных (реквизитов)

Поскольку каждая ячейка на форме должна быть связана со своим уникальным хранилищем данных, нам нужно заранее подготовить все необходимые колонки в `ТаблицеЗначений`. Если мы хотим видеть группы "П1", "П2", "П3", и в каждой из них "Цена" и "Количество", то наша `ТаблицаЗначений` должна иметь следующий набор колонок:

Колонки "П1", "П2", "П3" в данных нам не нужны, так как они будут представлены только визуальными группами на форме.

Рассмотрим, как создать эти реквизиты программно.


&НаСервере
Процедура СоздатьТаблицуНаСервере()

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

    // 3. Применяем изменения, добавляя все реквизиты на форму за один вызов
    ИзменитьРеквизиты(МассивРеквизитов);
    
КонецПроцедуры

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

Шаг 2: Создание элементов формы (таблицы, групп, полей)

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

Проанализируем алгоритм:

  1. Добавляем на форму элемент типа ТаблицаФормы и связываем его с созданным ранее реквизитом `СписокТоваров`.
  2. Добавляем простое поле для колонки "Товар". Его родителем будет сама таблица.
  3. Запускаем цикл (например, от 1 до 3) для создания групп П1, П2, П3.
  4. Внутри цикла:
    • Создаем элемент-группу. Правильный способ: используем Элементы.Добавить(ИмяГруппы, Тип("ГруппаФормы"), Родитель), а затем устанавливаем свойство Вид = ВидГруппыФормы.ГруппаКолонок. Родителем этой группы является наша таблица.
    • Создаем поля "Цена" и "Количество". Их родителем будет только что созданная группа.
    • Устанавливаем для полей полный путь к данным. Это критически важный момент. Путь должен состоять из имени реквизита таблицы и имени реквизита колонки, например, "СписокТоваров.ЦенаП1".

Посмотрим на итоговый код, который объединяет создание реквизитов и элементов формы.


&НаСервере
Процедура СформироватьТаблицуСГруппами()

    // === ШАГ 1: СОЗДАНИЕ РЕКВИЗИТОВ ===
    
    МассивРеквизитов = Новый Массив;
    ИмяРеквизитаТаблицы = "СписокТоваров";
    
    // Основной реквизит таблицы
    МассивРеквизитов.Добавить(Новый РеквизитФормы(ИмяРеквизитаТаблицы, 
        Новый ОписаниеТипов("ТаблицаЗначений"), "", "Список товаров"));
    
    // Реквизиты колонок
    МассивРеквизитов.Добавить(Новый РеквизитФормы("Товар", 
        Новый ОписаниеТипов("СправочникСсылка.Номенклатура"), ИмяРеквизитаТаблицы));
    
    Для Сч = 1 По 3 Цикл
        ИмяПериода = "П" + Сч;
        МассивРеквизитов.Добавить(Новый РеквизитФормы("Цена" + ИмяПериода, 
            Новый ОписаниеТипов("Число"), ИмяРеквизитаТаблицы));
        МассивРеквизитов.Добавить(Новый РеквизитФормы("Количество" + ИмяПериода, 
            Новый ОписаниеТипов("Число"), ИмяРеквизитаТаблицы));
    КонецЦикла;
    
    ИзменитьРеквизиты(МассивРеквизитов);
    
    // === ШАГ 2: СОЗДАНИЕ ЭЛЕМЕНТОВ ФОРМЫ ===
    
    // Добавляем таблицу на форму (предположим, в корень элементов)
    ЭлементТаблица = Элементы.Добавить("ТаблицаТоваров", Тип("ТаблицаФормы"), ЭтаФорма);
    ЭлементТаблица.ПутьКДанным = ИмяРеквизитаТаблицы;
    
    // Добавляем колонку "Товар"
    ПолеТовар = Элементы.Добавить("ПолеТовар", Тип("ПолеФормы"), ЭлементТаблица);
    ПолеТовар.Вид = ВидПоляФормы.ПолеВвода;
    ПолеТовар.ПутьКДанным = ИмяРеквизитаТаблицы + ".Товар";
    ПолеТовар.Заголовок = "Товар";
    
    // В цикле создаем группы и их колонки
    Для Сч = 1 По 3 Цикл
        ИмяПериода = "П" + Сч;
        
        // Создаем группу колонок
        ГруппаП = Элементы.Добавить("Группа" + ИмяПериода, Тип("ГруппаФормы"), ЭлементТаблица);
        ГруппаП.Вид = ВидГруппыФормы.ГруппаКолонок;
        ГруппаП.Заголовок = ИмяПериода;
        
        // Добавляем поле "Цена" внутрь группы
        ПолеЦена = Элементы.Добавить("ПолеЦена" + ИмяПериода, Тип("ПолеФормы"), ГруппаП);
        ПолеЦена.Вид = ВидПоляФормы.ПолеВвода;
        ПолеЦена.Заголовок = "Цена";
        // Указываем ПОЛНЫЙ путь к данным!
        ПолеЦена.ПутьКДанным = ИмяРеквизитаТаблицы + ".Цена" + ИмяПериода;
        
        // Добавляем поле "Количество" внутрь группы
        ПолеКоличество = Элементы.Добавить("ПолеКоличество" + ИмяПериода, Тип("ПолеФормы"), ГруппаП);
        ПолеКоличество.Вид = ВидПоляФормы.ПолеВвода;
        ПолеКоличество.Заголовок = "Кол-во";
        // Указываем ПОЛНЫЙ путь к данным!
        ПолеКоличество.ПутьКДанным = ИмяРеквизитаТаблицы + ".Количество" + ИмяПериода;
    КонецЦикла;

КонецПроцедуры

Выводы и частые ошибки

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

  1. Одна колонка в данных — одно поле на форме. Не пытайтесь связать несколько полей на форме с одной и той же колонкой в ТаблицеЗначений. Это приведет к тому, что при изменении значения в одной ячейке, оно синхронно изменится во всех "связанных" ячейках в той же строке.
  2. Правильное создание группы. Группа колонок создается как обычный элемент ГруппаФормы, у которого свойству Вид присваивается значение ВидГруппыФормы.ГруппаКолонок.
  3. Полный путь к данным. В свойстве ПутьКДанным для полей внутри таблицы всегда указывайте полный путь, начиная с имени реквизита самой таблицы: "ИмяТаблицы.ИмяКолонки". Ошибка с указанием только имени колонки — одна из самых частых.
  4. Правильная иерархия элементов. Поля, которые должны находиться внутри группы, должны добавляться с указанием этой группы в качестве родителя. Поля, которые должны быть на верхнем уровне, добавляются с указанием таблицы в качестве родителя.

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

← На главную