Как транспонировать табличную часть в 1С: размещение реквизитов в строках, а строк в колонках

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

В процессе разработки конфигураций на платформе 1С нередко возникает задача нестандартного отображения табличных данных. Классический пример: документ содержит учет параметров оборудования (например, агрегатов электростанции). Число самих агрегатов невелико (от 1 до 5), однако список контролируемых параметров насчитывает более 10–15 позиций (наработка, температура охлаждающей жидкости, давление масла, результаты тестов и прочее). Если выводить эти данные через стандартную табличную часть документа, таблица получается чрезвычайно широкой, неудобной для восприятия и требует постоянной горизонтальной прокрутки.

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

Ограничения платформы 1С при работе с табличными частями

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

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

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

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

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

Посмотрим на общую схему реализации:

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

Рассмотрим пример кода для серверного формирования структуры колонок и элементов формы:


&НаСервере
Процедура СформироватьМатрицуНаСервере()

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

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

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

Способ 2. Использование редактируемого табличного документа (ПолеТабличногоДокумента)

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

Разберем достоинства и особенности этого решения:

  1. Гибкость разметки: табличный документ позволяет легко объединять ячейки, раскрашивать строки и колонки, задавать границы, ширину и сворачиваемые группировки.
  2. Типизация ввода: для каждой конкретной ячейки можно задать свойство СодержитЗначение = Истина и назначить точный ТипЗначения (число, строка, дата или ссылка на справочник). В этом случае ячейка будет открывать стандартное окно выбора или калькулятор платформы.
  3. Снятие защиты: для обеспечения возможности редактирования у элемента формы и ячеек устанавливаются свойства ТолькоПросмотр = Ложь и Защита = Ложь.

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

Способ 3. Интерфейсный паттерн «Мастер — Деталь» (Master-Detail)

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

Разделим экранную форму на две логические области:

  1. Левая часть (список агрегатов): компактная табличная часть документа, содержащая только 1–2 колонки (номер по порядку и наименование агрегата).
  2. Правая часть (детализация параметров): вертикальная панель, где друг под другом расположены поля ввода всех 10–15 параметров (наработка, температура, давление и т.д.).

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

Способ 4. Архитектурный подход: нормализация структуры данных

Проанализируем структуру хранения, если состав измеряемых характеристик заранее жестко не определен или меняется для разных типов агрегатов. Жестко прописывать десятки колонок в метаданных (ДавлениеМасла, ТемператураОЖ) — неоптимальное архитектурное решение.

Для таких задач проектируют табличную часть со следующей структурой колонок:

  1. Агрегат (ссылка на справочник агрегатов);
  2. Параметр (ссылка на ПланВидовХарактеристик или справочник параметров);
  3. ЗначениеПараметра (тип Характеристика.[ИмяПВХ]).

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

← На главную