При разработке сложных документов в 1С:Предприятие часто возникает задача отображения иерархических данных. Классический пример: список документов-оснований, где для каждого документа нужно указать свой перечень работ и их количество. Прямой поддержки «вложенных» табличных частей на уровне базы данных в 1С не существует, однако есть проверенные архитектурные паттерны, позволяющие добиться нужного результата. В этой статье мы подробно разберем, как реализовать механизм «Мастер-Деталь» и какие альтернативы существуют для визуализации таких данных.
Это наиболее стандартный и надежный способ для управляемых форм. Суть заключается в создании двух плоских табличных частей, которые логически связаны между собой уникальным идентификатором. Рассмотрим этот процесс по шагам.
1. Настройка метаданных в конфигураторе
В документе создаем две табличные части:
Основания (Мастер-таблица) — здесь будут храниться заголовки (например, ДокументОснование).СоставРабот (Деталь-таблица) — здесь будут храниться подчиненные строки.Важный момент: в обе табличные части необходимо добавить реквизит КлючСвязи. Для обеспечения уникальности лучше всего использовать тип УникальныйИдентификатор или, в более простых случаях, Число.
2. Программная логика на форме
Чтобы при перемещении курсора в первой таблице во второй отображались только относящиеся к ней строки, проанализируем событие ПриАктивизацииСтроки. Разберем пример кода:
&НаКлиенте
Процедура ОснованияПриАктивизацииСтроки(Элемент)
ТекущиеДанные = Элементы.Основания.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
// Устанавливаем отбор во второй таблице по ключу связи
Элементы.СоставРабот.ОтборСтрок = Новый ФиксированнаяСтруктура("КлючСвязи", ТекущиеДанные.КлючСвязи);
КонецЕсли;
КонецПроцедуры
3. Генерация ключа при добавлении строк
Чтобы связь не терялась, при создании новой строки в основной таблице нужно генерировать новый уникальный ключ. Посмотрим, как это сделать:
&НаКлиенте
Процедура ОснованияПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
Если НоваяСтрока И НЕ Копирование Тогда
ТекущиеДанные = Элементы.Основания.ТекущиеДанные;
ТекущиеДанные.КлючСвязи = Новый УникальныйИдентификатор;
КонецЕсли;
КонецПроцедуры
Преимущества этого метода: данные хранятся в типовых табличных частях, что позволяет легко использовать их в запросах и отчетах. Недостаток: пользователь видит две отдельные таблицы на форме, а не одну вложенную структуру.
Если задача стоит именно в визуальном представлении «одна таблица внутри другой», проанализируем использование объекта ДеревоЗначений. Этот объект позволяет создавать неограниченное количество уровней вложенности.
Рассмотрим алгоритм работы с деревом:
ДеревоЗначений.Пример программного добавления узлов в дерево:
// Создаем строку верхнего уровня (Документ-основание)
НоваяСтрокаОснование = ДеревоДанных.ПолучитьОбъект().Строки.Добавить();
НоваяСтрокаОснование.Наименование = "Заказ №1";
// Создаем подчиненную строку (Работа)
НоваяСтрокаРабота = НоваяСтрокаОснование.Строки.Добавить();
НоваяСтрокаРабота.Наименование = "Монтаж оборудования";
НоваяСтрокаРабота.Количество = 1;
Выясним важную особенность: ДеревоЗначений нельзя напрямую сохранить как реквизит документа. Поэтому перед записью документа вам придется реализовать обратный процесс — «развертывание» дерева обратно в плоские табличные части.
В современной разработке на платформе 8.3.10 и выше часто применяется метод сериализации. Если подчиненные данные не нужно выбирать в запросах (например, это вспомогательные расчеты), их можно хранить в одной ячейке основной таблицы.
Проанализируем шаги реализации:
ДанныеСтроки с типом Строка (неограниченной длины).Посмотрим на пример упаковки данных:
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ТаблицаРабот);
СтрокаДляХранения = ЗаписьJSON.Закрыть();
Этот метод значительно упрощает структуру метаданных, так как вам не нужно плодить множество табличных частей. Однако помните, что данные внутри JSON-строки «невидимы» для системы компоновки данных (СКД), пока вы не преобразуете их обратно в таблицу программно.
Выбор конкретного метода зависит от требований к производительности и удобству пользователя:
При реализации связи через ключи, всегда используйте УникальныйИдентификатор. Избегайте связи по номеру строки (НомерСтроки), так как при удалении или сортировке строк в основной таблице номера пересчитываются, и связь с подчиненными строками в другой таблице будет безвозвратно нарушена.
Рассмотренные подходы позволяют гибко обходить ограничения платформы и создавать интерфейсы любой сложности, обеспечивая при этом надежное хранение данных в структуре 1С:Предприятия.