Разработка и Конфигурация · 10 мин
Как выгрузить иерархический справочник 1С в дерево
Как выгрузить иерархический справочник 1С в дерево: запрос с итогами по иерархии, обход выборки, выгрузка в дерево значений, файл и Excel.
Иерархический справочник в 1С хранит элементы и группы, связанные через реквизит «Родитель». Когда такой справочник нужно выгрузить — в дерево значений, файл, Excel или другую систему — важно не просто получить список записей, а сохранить структуру вложенности: кто в какой группе лежит и на каком уровне находится.
Способ выгрузки зависит от цели. Для отображения на форме достаточно динамического списка или дерева значений. Для обмена с внешней системой обычно строят запрос с итогами по иерархии или рекурсивный обход и сериализуют результат в XML, JSON или табличный документ. Ниже разобраны рабочие варианты для управляемых и обычных форм.
Материал ориентирован на платформу 1С:Предприятие 8.3 и типовые механизмы: запросы с конструкцией «ИТОГИ ПО ... ИЕРАРХИЯ», объект «ДеревоЗначений», стандартные средства выгрузки данных. Код приведён на встроенном языке и легко адаптируется под любой иерархический справочник — «Номенклатура», «Подразделения», «Статьи затрат» и другие.
Как устроена иерархия справочника и что именно нужно выгрузить
В иерархическом справочнике каждый элемент имеет системный реквизит «Родитель» — ссылку на группу (или элемент, если иерархия «элементов», а не «групп и элементов»). Корневые записи имеют пустого родителя. Глубина вложенности не ограничена платформой, поэтому обход должен быть либо рекурсивным, либо построенным на механизме иерархических итогов запроса.
Перед выгрузкой определите, что считать результатом: дерево на форме для пользователя, файл со структурой для внешней системы или плоская таблица с колонкой «Родитель» и «Уровень». От этого зависит инструмент: ДеревоЗначений, запись XML/JSON или табличный документ.
Выгрузка в дерево значений запросом с иерархическими итогами
Самый короткий путь — запрос с конструкцией «ИТОГИ ПО Родитель ИЕРАРХИЯ». Результат такого запроса можно выгрузить напрямую в ДеревоЗначений, и платформа сама построит вложенность строк без единой строки рекурсивного кода.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Код КАК Код,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления
|
|УПОРЯДОЧИТЬ ПО
| Наименование
|ИТОГИ ПО
| Номенклатура.Ссылка ИЕРАРХИЯ";
РезультатЗапроса = Запрос.Выполнить();
Дерево = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
Ключевой момент — параметр ОбходРезультатаЗапроса.ПоГруппировкамСИерархией в методе Выгрузить(). С обычным обходом «ПоГруппировкам» вложенность потеряется или дерево построится некорректно. Колонки дерева создаются автоматически по полям выборки.
Обратите внимание на сортировку: «УПОРЯДОЧИТЬ ПО Наименование» применится внутри каждого уровня, что обычно и требуется. Если нужен порядок «как в справочнике», используйте упорядочивание по иерархии — добавьте УПОРЯДОЧИТЬ ПО Ссылка ИЕРАРХИЯ.
Рекурсивный обход: когда запроса недостаточно
Иерархические итоги не подходят, если нужна нестандартная логика: выгрузить только одну ветку, пронумеровать уровни, вычислить путь вида «Группа/Подгруппа/Элемент» или отфильтровать элементы по условию, зависящему от предков. В этих случаях дерево строят рекурсивным обходом по родителям.
Процедура ДобавитьСтроки(СтрокиДерева, Родитель, Уровень)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ Ссылка, Наименование
|ИЗ Справочник.Номенклатура
|ГДЕ Родитель = &Родитель И НЕ ПометкаУдаления
|УПОРЯДОЧИТЬ ПО Наименование";
Запрос.УстановитьПараметр("Родитель", Родитель);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Строка = СтрокиДерева.Добавить();
Строка.Ссылка = Выборка.Ссылка;
Строка.Наименование = Выборка.Наименование;
Строка.Уровень = Уровень;
ДобавитьСтроки(Строка.Строки, Выборка.Ссылка, Уровень + 1);
КонецЦикла;
КонецПроцедуры
Начальный вызов выполняется с пустой ссылкой родителя: ДобавитьСтроки(Дерево.Строки, Справочники.Номенклатура.ПустаяСсылка(), 0). Минус подхода — один запрос на каждый узел, поэтому на больших справочниках (десятки тысяч элементов) он заметно медленнее иерархических итогов. Компромисс — выбрать весь справочник одним запросом в таблицу значений и строить дерево поиском по отбору «Родитель» в памяти.
Вывод дерева на форму
На управляемой форме дерево отображается через реквизит типа «ДеревоЗначений» с элементом формы «Таблица», у которой свойство «Отображение» установлено в «Дерево». Дерево значений — несериализуемый между вызовами тип, поэтому его заполняют при создании формы или в серверной процедуре, а при необходимости хранения между вызовами конвертируют через РеквизитФормыВЗначение / ЗначениеВРеквизитФормы.
Если задача — просто показать пользователю справочник деревом, выгружать ничего не нужно: динамический список формы списка иерархического справочника уже умеет режим «Дерево» (свойство «СпособПросмотра»). Ручная выгрузка в ДеревоЗначений оправдана, когда к дереву нужно добавить вычисляемые колонки, объединить данные нескольких источников или изменить структуру.
Выгрузка дерева в файл: XML, JSON и Excel
Для обмена с внешними системами дерево сериализуют. В XML иерархия естественно ложится на вложенные узлы; в JSON — на вложенные массивы «Дети»/«Children». Обходят дерево рекурсивно по коллекции Строки каждой строки.
Функция СтрокуВСтруктуру(СтрокаДерева)
Результат = Новый Структура;
Результат.Вставить("Код", СтрокаДерева.Код);
Результат.Вставить("Наименование", СтрокаДерева.Наименование);
Результат.Вставить("GUID", XMLСтрока(СтрокаДерева.Ссылка));
Дети = Новый Массив;
Для Каждого ПодСтрока Из СтрокаДерева.Строки Цикл
Дети.Добавить(СтрокуВСтруктуру(ПодСтрока));
КонецЦикла;
Результат.Вставить("Дети", Дети);
Возврат Результат;
КонецФункции
Полученная структура преобразуется в JSON через ЗаписьJSON и ЗаписатьJSON. Для Excel проще не вложенность, а «лесенка»: выводите строки дерева в табличный документ обходом с отступом (пробелами или свойством «Отступ» области ячеек) либо добавьте колонки «Уровень» и «Родитель» — так структуру легко восстановить при загрузке обратно.
В типовых конфигурациях также доступны универсальные механизмы: «Выгрузка и загрузка данных XML» (обработка с диска ИТС) переносит справочник целиком, сохраняя ссылки родителей, а в конфигурациях на БСП есть подсистема обмена данными. Они подходят для переноса между базами 1С, но не дают «читаемого» дерева для сторонней системы.
- 1Напишите запрос с «ИТОГИ ПО Ссылка ИЕРАРХИЯ» и нужными полями
- 2Выполните запрос и вызовите Выгрузить с параметром ПоГруппировкамСИерархией
- 3Проверьте, что в дереве появились вложенные строки (Строки.Количество() у корневых элементов)
- 4При необходимости обойдите дерево рекурсивно и сериализуйте в XML/JSON или выведите в табличный документ
- 5Проверьте результат на контрольной ветке с известной структурой
Проверка результата и типичные ошибки
Проверяйте выгрузку на справочнике, где структура известна заранее: возьмите одну группу с подгруппами и сравните количество элементов на каждом уровне с тем, что видно в форме списка. Полезный контроль — сравнить общее число строк дерева с количеством записей в справочнике без пометки удаления: расхождение означает потерянные или задвоенные ветки.
Отдельная ловушка — зацикливание. Если данные повреждены и элемент ссылается родителем сам на себя или на своего потомка, рекурсивный обход уйдёт в бесконечный цикл и завершится переполнением стека. В рекурсивных алгоритмах добавляйте защиту: ограничение максимального уровня (например, 50) или соответствие уже посещённых ссылок.
Что важно запомнить
Основной инструмент — запрос с «ИТОГИ ПО Ссылка ИЕРАРХИЯ» и выгрузка результата в ДеревоЗначений с обходом ПоГруппировкамСИерархией. Рекурсия нужна для нестандартной логики, файл получают рекурсивным обходом дерева с записью в XML/JSON, а для Excel сохраняют уровень и родителя в отдельных колонках.
Частые вопросы
Как выгрузить только одну ветку справочника, а не всё дерево?
Добавьте в запрос условие «Ссылка В ИЕРАРХИИ (&Группа)» — отбор вернёт саму группу и всех её потомков на любой глубине. Далее применяйте те же итоги по иерархии или рекурсивный обход, начиная с выбранной группы как корня.
Можно ли выгрузить дерево без программирования?
Частично. Список иерархического справочника можно вывести в табличный документ через «Ещё → Вывести список», но иерархия сохранится только визуально (отступами), без явной связи «родитель–потомок». Для машинно-читаемой структуры без кода не обойтись — нужен отчёт на СКД с иерархической группировкой или обработка.
Как построить дерево отчётом СКД без кода?
В схеме компоновки создайте группировку по полю «Ссылка» и в её свойствах укажите тип группировки «Иерархия». Отчёт сам построит дерево с раскрывающимися уровнями, а результат можно сохранить в табличный документ. Это удобно, когда выгрузка нужна аналитику, а не программисту.
Почему в выгрузке появились строки-дубли с пустыми данными?
Это итоговые записи группировки: при обходе результата с иерархией платформа возвращает и строки групп, и их детальные записи. При выгрузке в ДеревоЗначений с параметром ПоГруппировкамСИерархией это нормально — итоговые строки становятся родительскими узлами. Если дубли мешают при ручном обходе выборки, проверяйте ТипЗаписи() и обрабатывайте только нужные.
Как сохранить порядок элементов «как в справочнике»?
Используйте в запросе «УПОРЯДОЧИТЬ ПО Ссылка ИЕРАРХИЯ» — записи будут следовать в порядке внутренней нумерации с учётом вложенности. Если нужен пользовательский порядок (например, реквизит «ПорядокСортировки»), упорядочивайте по нему — сортировка применится внутри каждого уровня дерева.
Что делать, если глубина дерева очень большая и рекурсия падает?
Замените рекурсию на итеративный обход с явным стеком (таблица или массив «текущих узлов») — он не ограничен глубиной стека вызовов. Либо используйте иерархические итоги запроса: там обход выполняет платформа, и ограничение на глубину рекурсии встроенного языка не действует.