Как реализовать табличную часть в табличной части в реквизитах документа

Программист 1С v8.3 (Управляемые формы) Управленческий учет Промышленность, строительство и АПК
← На главную

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

Способ 1. Связь табличных частей через идентификатор строки (Master-Detail)

Это стандартный промышленный подход, который используется в большинстве типовых конфигураций (например, ERP или ЗУП). Суть метода заключается в том, что мы создаем две или более «плоских» табличных части и связываем их программно с помощью специального реквизита — ключа связи.

Проанализируем шаги реализации этого метода:

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

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


&НаКлиенте
Процедура ТестоПриАктивизацииСтроки(Элемент)
    ТекущиеДанные = Элементы.Тесто.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Элементы.Состав.ОтборСтрок = Новый ФиксированнаяСтруктура("КлючСвязи", -1);
    Иначе
        Элементы.Состав.ОтборСтрок = Новый ФиксированнаяСтруктура("КлючСвязи", ТекущиеДанные.КлючСвязи);
    КонецЕсли;
КонецПроцедуры

Важный нюанс: при добавлении новой строки в основную таблицу необходимо генерировать новый уникальный ключ связи. Если вы используете число, можно вычислять его как максимальный существующий ключ + 1. Если УникальныйИдентификатор — использовать встроенную функцию платформы.

Способ 2. Автоматизация удаления и копирования (Каскадные действия)

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

Для решения этой проблемы необходимо прописать логику в событии ПередУдалением или ПослеУдаления основной таблицы. Выясним, как это выглядит в коде:


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

Аналогично стоит поступить и с копированием. При копировании строки документа стандартными средствами 1С, ключи связи в новой строке будут идентичны старым, что приведет к перемешиванию данных. Разберем по шагам: в событии ПриКопировании или через специализированную команду копирования нужно сгенерировать новый КлючСвязи для новой строки-родителя и продублировать все строки-потомки с этим новым ключом.

Способ 3. Визуализация через Дерево значений

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

Проанализируем особенности этого подхода:

  1. Объект ДеревоЗначений не может быть реквизитом документа. Данные всё равно придется хранить в плоских табличных частях (как в первом способе).
  2. При открытии формы документа мы программно заполняем дерево на основании данных из табличных частей.
  3. Перед записью документа мы «сворачиваем» дерево обратно в плоские таблицы.

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

Способ 4. Использование отдельного справочника для спецификаций

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

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

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

Способ 5. Интерфейсный паттерн «Всплывающее окно»

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

Это позволяет сконцентрировать внимание пользователя на конкретной задаче и избежать ошибок при случайном переключении строк в основной таблице.

Резюме

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

← На главную