Как программно создавать вложенные таблицы в 1С и выводить параметры товаров из Excel

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

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

Метод 1: Использование вложенных объектов ТаблицаЗначений

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

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


// Создаем основную таблицу для хранения списка товаров
ТабТовары = Новый ТаблицаЗначений;
ТабТовары.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка"));
ТабТовары.Колонки.Добавить("ТаблицаПараметров", Новый ОписаниеТипов("ТаблицаЗначений"));

// Добавляем первый товар
НоваяСтрока = ТабТовары.Добавить();
НоваяСтрока.Наименование = "Процессор Intel Core i9";

// Создаем вложенную таблицу параметров для этого товара
ТабПараметров = Новый ТаблицаЗначений;
ТабПараметров.Колонки.Добавить("Характеристика", Новый ОписаниеТипов("Строка"));
ТабПараметров.Колонки.Добавить("Значение", Новый ОписаниеТипов("Строка"));

// Заполняем параметры
СтрПараметр = ТабПараметров.Добавить();
СтрПараметр.Характеристика = "Частота";
СтрПараметр.Значение = "5.2 ГГц";

СтрПараметр = ТабПараметров.Добавить();
СтрПараметр.Характеристика = "Ядра";
СтрПараметр.Значение = "16";

// Помещаем таблицу параметров в ячейку основной таблицы
НоваяСтрока.ТаблицаПараметров = ТабПараметров;

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


Для Каждого СтрокаТовар Из ТабТовары Цикл
    Сообщить("Товар: " + СтрокаТовар.Наименование);
    
    // Получаем вложенную таблицу из ячейки
    ТекущиеПараметры = СтрокаТовар.ТаблицаПараметров;
    
    Для Каждого СтрокаПараметр Из ТекущиеПараметры Цикл
        Сообщить(" - " + СтрокаПараметр.Характеристика + ": " + СтрокаПараметр.Значение);
    КонецЦикла;
КонецЦикла;

Метод 2: Реализация интерфейса «Мастер-Деталь» на управляемой форме

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

Шаг 1. Подготовка реквизитов формы. Нам необходимо создать два реквизита формы типа ТаблицаЗначений:

  1. СписокТоваров (Колонки: Идентификатор, Название).
  2. ПараметрыТовара (Колонки: Характеристика, Значение).

Шаг 2. Хранение данных. Чтобы параметры не терялись, мы можем хранить их в скрытом реквизите (например, в соответствии или в той же вложенной таблице, как в Методе 1), либо динамически подгружать из внешнего источника или кэша.

Шаг 3. Обработка события активации строки. Основным инструментом здесь выступает событие ПриАктивизацииСтроки для элемента формы, отображающего СписокТоваров. Рассмотрим программную реализацию обработчика:


&НаКлиенте
Процедура СписокТоваровПриАктивизацииСтроки(Элемент)
    ТекущиеДанные = Элементы.СписокТоваров.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Вызываем серверный метод для обновления таблицы параметров
    ОбновитьТаблицуПараметровНаСервере(ТекущиеДанные.Идентификатор);
КонецПроцедуры

&НаСервере
Процедура ОбновитьТаблицуПараметровНаСервере(ИдентификаторТовара)
    // Очищаем текущую таблицу параметров на форме
    ПараметрыТовара.Очистить();
    
    // Предположим, что данные хранятся во временном хранилище или глобальной переменной
    // Здесь мы находим параметры по идентификатору и заполняем таблицу ПараметрыТовара
    // ... логика поиска ...
КонецПроцедуры

Метод 3: Использование Дерева Значений

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

Посмотрим на пример создания структуры в дереве значений:


Дерево = Новый ДеревоЗначений;
Дерево.Колонки.Добавить("Наименование");
Дерево.Колонки.Добавить("Значение");

// Добавляем узел верхнего уровня (Товар)
СтрокаТовар = Дерево.Строки.Добавить();
СтрокаТовар.Наименование = "Смартфон";

// Добавляем подчиненные строки (Параметры)
СтрокаПараметр = СтрокаТовар.Строки.Добавить();
СтрокаПараметр.Наименование = "Цвет";
СтрокаПараметр.Значение = "Черный";

СтрокаПараметр = СтрокаТовар.Строки.Добавить();
СтрокаПараметр.Наименование = "Память";
СтрокаПараметр.Значение = "128 Гб";

Важный момент: Чтобы отобразить это на форме, нужно создать реквизит формы с типом ДеревоЗначений, перетащить его на элементы формы и в свойствах таблицы указать режим отображения «Дерево». Это позволит пользователю разворачивать и сворачивать список параметров для каждого товара.

Метод 4: Динамическое создание колонок при загрузке из Excel

Часто состав параметров товара в Excel заранее неизвестен (например, у одного товара 3 параметра, а у другого 10 разных характеристик в разных столбцах). В таких случаях нам потребуется программная генерация колонок формы.

Выясним алгоритм действий:

  1. Сначала мы считываем заголовок Excel-файла, чтобы определить список всех возможных уникальных характеристик.
  2. Используем метод ИзменитьРеквизиты() для программного добавления колонок в объект ТаблицаЗначений на форме.
  3. Создаем элементы формы типа ПолеФормы и связываем их с новыми реквизитами.

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


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

Особенности работы с Excel

При генерации таблиц циклами из внешних файлов (Excel), крайне важно разделять процесс чтения и процесс структурирования. Рассмотрим рекомендации по оптимизации:

1. Отказ от COM-объектов. Если версия платформы позволяет, используйте объект ЧтениеXLSX. Это работает нативно, быстрее и не требует наличия установленного Microsoft Excel на сервере.

2. Буферизация данных. Сначала считайте весь лист Excel в плоскую «техническую» ТаблицуЗначений. И только потом, вторым проходом цикла, распределяйте данные по вложенным структурам или деревьям. Прямое обращение к ячейкам Excel внутри сложной логики создания таблиц значительно замедляет выполнение кода.

3. Использование идентификаторов. При загрузке товаров и их параметров из разных листов Excel обязательно создавайте временный ключ связи (например, артикул или номер строки), чтобы точно сопоставить параметры конкретному товару.

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

← На главную