Как загрузить таблицу значений в ячейку другой таблицы значений в 1С

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

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

Причина возникновения проблемы: элементы формы и источники данных

Разберем типичную ошибку при работе с табличными полями. Попытка записать данные подчиненного поля непосредственно через элементы формы, например ЭлементыФормы.ГотоваяПродукция.ТекущаяСтрока.ТЗ = Комплект, приводит к непредсказуемому behavior или получению пустого значения при обновлении подчиненной таблицы.

Выясним причину такого поведения:

  1. Разделение визуального элемента и данных: Объект ТабличноеПоле — это лишь визуальное «окно» для отображения информации. Непосредственная работа с данными должна происходить с объектом-источником — ТаблицаЗначений.
  2. Работа с ссылками на объекты: Таблица значений является ссылочным объектом. При прямом присвоении Стр.ТЗ = Комплект в ячейку помещается ссылка на тот же самый объект таблицы в памяти. Когда подчиненная таблица Комплект очищается или перезаполняется (например, через метод Очистить()), данные сбрасываются и внутри ячейки родительской таблицы.

Пошаговое решение задачи

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

Шаг 1. Инициализация колонки источника данных

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


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

Шаг 2. Копирование подчиненной таблицы в ячейку строки

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

Посмотрим на пример функции сохранения:


Функция СохранимТЗДляГотовойПрод()
    Если ГотоваяПродукция.Количество() > 0 Тогда
        // Получаем индекс текущей выбранной строки
        ТекущиеДанные = ЭлементыФормы.ГотоваяПродукция.ТекущиеДанные;
        Если ТекущиеДанные <> Неопределено Тогда
            ИндексТекСтроки = ГотоваяПродукция.Индекс(ТекущиеДанные);
            Стр = ГотоваяПродукция[ИндексТекСтроки];
            
            // Сохраняем копию таблицы значений в ячейку
            Стр.ТЗ = Комплект.Скопировать();
        КонецЕсли;
    КонецЕсли;
КонецФункции

Шаг 3. Считывание данных при активизации строки

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


Процедура ГотоваяПродукцияПриАктивизацииСтроки(Элемент)
    ЗаполнимКомплектЗначениямиСпецификации();
КонецПроцедуры

Функция ЗаполнимКомплектЗначениямиСпецификации()
    ТекущиеДанные = ЭлементыФормы.ГотоваяПродукция.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат Неопределено;
    КонецЕсли;

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

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

Проанализируем ключевые особенности, которые необходимо учитывать при работе со сложными вложенными структурами:

Альтернативные архитектурные решения

Если структура данных предполагает иерархию, рассмотрим альтернативные штатные варианты платформы:

  1. Использование Дерева Значений (ДеревоЗначений): Если данные имеют древовидную структуру («Продукция» -> «Компоненты»), наилучшим решением будет использование `ДереваЗначений`. Элемент управления `ТабличноеПоле` умеет работать с деревом из коробки, предоставляя пользователю удобные плюсики для раскрытия и сворачивания строк.
  2. Связь двух плоских таблиц по ключу: Вместо вложения таблиц друг в друга создаются две независимые таблицы: родительская (с колонкой `КлючСтроки`) и подчиненная (с колонкой `КлючСвязи`). При выборе строки в первой таблице подчиненное табличное поле фильтруется по соответствию ключей. Это исключает необходимость постоянного копирования объектов.
← На главную