Доброго времени!
Встрял при программном рисовании вывода в Word, как организовать иерархический список произвольной глубины (зависит от входящей структуры данных).
Гуглить - пока результата не дало.
Макеты подготовленные не подходят, так как структура документа может оказаться любой каждый раз. Все с первой строчки программное создание.

Пробовал из отдельно созданного макета с областями брать область нужного уровня заголовка, но вставляется в мой формируемый документ как обычный текст, теряется форматирование.

И что бы все нумерованные строки были заголовками и иерархическими и отображались в панели навигации созданного документа.
Море всяких примеров создания вордовых документов, но 99% копипаст идет пары типовых приёмов. Шаг влево и встрял сразу.

Должно получиться в виде таком:
---
наверное надо изучить методы Com объекта Document(Word) на сайте мелкомягких

Ещё как вариант сохранить макросы и их изучать
Как пример:

```1c
    Selection.TypeText Text:="заголовое"
    Selection.St yle = ActiveDocument.Styles("Заголовок 1")
```
---
Гуглить - пока результата не дало. А вот это нагуглилось?

```1c
    // В области закладки 4 сформируем нумерованный список
    ThisDocument.Bookmarks("Закладка4").Range.S_elect();
    S_election = Word.S_election; // активная (выделенная) область будет начинаться
    // от закладки 4)
```
---
Да, это видел и от туда пока получилось просто пронумеровать подряд каждый абзац нумерованным списком без заголовков. Конечное решение пока от сюда не родилось.
---
пока получилось просто пронумеровать подряд каждый абзац нумерованным списком без заголовков Ну, тогда действительно надо разбираться с методами COM, их у MS дофига и больше.

Может быть, что-то удастся почерпнуть отсюда: https://scriptcoding.ru/sozdanie-mnogourovnevoho-spiska-word/

Но там уже не 1С рассматривается, примеры на VBS и JavaScript.

Хотя, ИМХО, программисту разобраться можно.
---
наверное надо изучить методы Com объекта Document(Word) на сайте мелкомягких

Ещё как вариант сохранить макросы и их изучать
Как пример:

```1c
    Selection.TypeText Text:="заголовое"
    Selection.St yle = ActiveDocument.Styles("Заголовок 1")
```
---
Selection.St yle = ActiveDocument.Styles("Заголовок 1")

А вот это уже да, ближе к делу. Теперь обработать уровень глубины заголовка ещё. Но именно список мне не пронумеровало. Хотя с начала результат обрадовал, но у меня нумерация сформирована уже в структуре строк была и вывелась, я было УРА крикнул сразу.
Тут похоже можно как-то сами стили заголовков создать и сохранить в пустом шаблоне в макет и его заполнять, получив из макета.
Давно ворд не трогал очень. Помню с этими стилями лет 5 назад навспотел. Шаблон сформирован четко по жестким требованиям был у меня для юристов. Но у некоторых отдельных пользователей - все отступы уплывали и документы заворачивать стали. Оказалось у них стили заголовков с такими же названиями под себя настроены. Тогда в шаблоне просто все стили очистил и стало у всех одинаково рисовать.
Сейчас попробую ещё в эту сторону покопать.
Сейчас нарисую заголовки с нужной глубиной нумерации, сохраню шаблон в макет пустой. И попытаюсь. Ещё корректно бы создать все эти заголовки, ворд не моя стихия...
---
да я тоже не силен в MS Word. Не понимаю чем отличаются стиль заголовка и стиль обычного текста, т.е. как там задается уровень заголовка.
Наверное должно быть какое-то свойство.
Удачи Вам в изучении
---
В итоге первый набросок вышел в таком виде.
Ещё раз. Пришлось для исполнения решения в таком виде - создать пустой шаблон ворда с подготовленными заголовками разных уровней.Прикладываю, может кому пригодится тоже.
Ещё первым куском кода вставка титульного листа из прикрепленного файла к элементу в первой строке массива идет. У меня определяется не по именно первой строке, а там ещё элемент должен быть с свойством Строка.Порядок = 0 в котором именно титульный лист положили.
Код не ругать сильно, поправки принимаются. Это первая итерация ещё.
Там ещё будут помимо титульного листа и другие вставки из прикрепленных файлов.

```1c
    &НаКлиенте
    Процедура ОбработатьВыводWORD(МассивСтрокСУровнями)

    Отладка = Истина;

    #Если ВебКлиент Тогда
    ИмяВременногоФайлаДок = КаталогВременныхФайлов() + Строка(Новый УникальныйИдентификатор) + ".DOCX";
    #Иначе
    ИмяВременногоФайлаДок = ПолучитьИмяВременногоФайла("DOCX");
    #КонецЕсли

    ДвоичныеДанные = ПолучитьМакетНаСервере("ПустойМакетWORD");

    COMОбъект = Неопределено;
    СтруктураWord = ПолучитьМакетMSWord(ДвоичныеДанные, ИмяВременногоФайлаДок);

    СтруктураWord.COMСоединение.Application.Options.CheckSpellingAsYouType = Ложь;
    СтруктураWord.Вставить("ДокументWord", СтруктураWord.COMСоединение.ActiveDocument);
    Если Отладка Тогда
    СтруктураWord.COMСоединение.Visible = Истина;
    КонецЕсли;

    ВставитьТегиДокумента(СтруктураWord, МассивСтрокСУровнями);

    Документ = СтруктураWord.COMСоединение.ActiveDocument;

    Документ.Select();
    Selection = Документ.Application.Selection;
    Selection.Collapse();
    Документ.ActiveWindow.View.Type = 3;

    Если НЕ Отладка Тогда
    СтруктураWord.COMСоединение.Visible = Истина;
    КонецЕсли;

    КонецПроцедуры

    &НаСервере
    Функция ПолучитьДД(Элемент)

    Возврат РаботаСФайлами.ДвоичныеДанныеФайла(Элемент.ХранимыйФайл);

    КонецФункции

    &НаКлиенте
    Процедура ВставитьТегиДокумента(СтруктураWord, МассивСтрокСУровнями) // ВставкаТекста

    Документ = СтруктураWord.COMСоединение.ActiveDocument;
    Документ.Select();
    Text = Документ.Application.Selection;
    Text.WholeStory();
    Text.Delete(1, 1);
    Для Каждого Строка ИЗ МассивСтрокСУровнями Цикл
    Если Строка.Порядок = 0 Тогда // Вставить Титульный лист
    Если ЗначениеЗаполнено(Строка.ХранимыйФайл) Тогда
    #Если ВебКлиент Тогда
    ИмяВременногоФайла_N = КаталогВременныхФайлов() + Строка(Новый УникальныйИдентификатор) + ".DOCX";
    #Иначе
    ИмяВременногоФайла_N = ПолучитьИмяВременногоФайла("DOCX");
    #КонецЕсли
    ДвоичныеДанные_N = ПолучитьДД(Строка);
    ДвоичныеДанные_N.Записать(ИмяВременногоФайла_N);
    //СтруктураWord.COMСоединение.ActiveDocument.Application.Selection.EndKey(6);
    //СтруктураWord.COMСоединение.ActiveDocument.Application.Selection.InsertFile(ИмяВременногоФайла_N,,, Ложь);
    //СтруктураWord.COMСоединение.ActiveDocument.Application.Selection.InsertBreak(2);
    Text.EndKey(6);
    Text.InsertFile(ИмяВременногоФайла_N,,, Ложь);
    Text.InsertBreak(2);
    Иначе
    Text.TypeText("Отсутствует титульный лист!");
    Text.InsertBreak(2);
    КонецЕсли;
    Продолжить;
    КонецЕсли;

    Text.TypeText(Строка.НомерПункта + " " + Строка.СведенияПроекта);
    Заголовок = "Заголовок 1";
    Если Строка.УровеньЗаголовка = 1 Тогда
    Заголовок = "Заголовок 1";
    ИначеЕсли Строка.УровеньЗаголовка = 2 Тогда
    Заголовок = "Заголовок 2";
    ИначеЕсли Строка.УровеньЗаголовка = 3 Тогда
    Заголовок = "Заголовок 3";
    ИначеЕсли Строка.УровеньЗаголовка = 4 Тогда
    Заголовок = "Заголовок 4";
    ИначеЕсли Строка.УровеньЗаголовка = 5 Тогда
    Заголовок = "Заголовок 5";
    ИначеЕсли Строка.УровеньЗаголовка = 6 Тогда
    Заголовок = "Заголовок 6";
    ИначеЕсли Строка.УровеньЗаголовка = 7 Тогда
    Заголовок = "Заголовок 7";
    КонецЕсли;
    Text.St yle = СтруктураWord.COMСоединение.ActiveDocument.Styles(Заголовок);

    Text.TypeParagraph();
    Text.St yle = СтруктураWord.COMСоединение.ActiveDocument.Styles("Обычный");

    Text.TypeText(Символы.ВК);
    Если ЗначениеЗаполнено(Строка.Пояснение) Тогда
    Текст = Строка.Пояснение;
    ИначеЕсли ЗначениеЗаполнено(Строка.Пояснение) Тогда
    Текст = Строка.Пояснение;
    Иначе
    Текст = "Пустой текст.";
    КонецЕсли;
    Text.TypeText(Текст);
    Text.St yle = СтруктураWord.COMСоединение.ActiveDocument.Styles("Обычный");
    Text.TypeText(Символы.ВК);
    КонецЦикла;

    КонецПроцедуры
```
---
St yle Странно, почему-то код рвется при вставке в пост. Это же слово в других постах так же рваное встречал и думал зачем так портят текст, умышленно что ли, что бы подумали копипастеры над смыслом? А тут вставил и так же рваный код вышел, редактирование не помогает...
---
да, я тоже это заметил
---
Советую смотреть на редактирование docx через средства работы с xml, в БСП если не ошибаюсь они есть, COM - легаси
---
Пока не приходилось, но про такое направление знаю. Вообще не часто с ПФ работаю и быстро выветривается опыт из головы.
---
Ещё довыложу кусочек тут по сбору массива строк моего. Тоже искал, как разобрать иерархический справочник по уровням в нужном порядке для печати потом всех его элементов и тоже способов внятных и понятных сходу не нашел и написал свою рекурсию.
Замечу, у меня при сборке ещё собираются прикрепленные файлы и в дереве в иерархии образуются дополнительно строки подчиненные ещё. Не было бы этого соединения - то первое условие в разборе рекурсии было бы проще, если бы только сам справочник один разбирать.
В справочнике создано поле Порядок, для сортировки. Номер пункта же поле, там пользователи для себя руками формировали нумерацию иерархическую, типа 1.4.3, я её не использую, только для сравнения верности формирования заголовков в ворде временно вывел.
#ИерархияСправочника

```1c
    &НаСервере
    Процедура ПолучитьНаСервере(МассивСтрокСУровнями,Владелец)

    Запрос = Новый Запрос;
    Запрос.Текст = "
    |ВЫБРАТЬ
    | трСведенияПроекта.Ссылка КАК СведенияПроекта,
    | ЕСТЬNULL(оснФайлыОбъектов.ХранимыйФайл, НЕОПРЕДЕЛЕНО) КАК ХранимыйФайл,
    | трСведенияПроекта.НомерПункта КАК НомерПункта,
    | трСведенияПроекта.Содержание КАК Содержание,
    | трСведенияПроекта.Порядок КАК Порядок,
    | трСведенияПроекта.Комментарий КАК Комментарий,
    | трСведенияПроекта.ЭтоГруппа КАК ЭтоГруппа,
    | трСведенияПроекта.Пояснение КАК Пояснение
    |ИЗ
    | Справочник.трСведенияПроекта КАК трСведенияПроекта
    | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.оснФайлыОбъектов КАК оснФайлыОбъектов
    | ПО (оснФайлыОбъектов.ВладелецФайла = трСведенияПроекта.Ссылка)
    |ГДЕ
    | трСведенияПроекта.Владелец = &Владелец
    | И НЕ трСведенияПроекта.ПометкаУдаления
    |
    |УПОРЯДОЧИТЬ ПО
    | Порядок
    |ИТОГИ ПО
    | СведенияПроекта ИЕРАРХИЯ
    |";

    Запрос.УстановитьПараметр("Владелец", Владелец);
    РезультатЗапроса = Запрос.Выполнить();
    ДеревоРезультат = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией).Строки;

    Для Каждого СтрокаУровня_1 Из ДеревоРезультат Цикл
    СтруктураСтроки = Новый Структура("НомерПункта,Порядок,Пояснение,СведенияПроекта,Содержание,ЭтоГруппа,УровеньЗаголовка,ХранимыйФайл");
    ЗаполнитьЗначенияСвойств(СтруктураСтроки,СтрокаУровня_1);
    СтруктураСтроки.УровеньЗаголовка = 1;
    МассивСтрокСУровнями.Добавить(СтруктураСтроки);
    РазложитьДеревоРекурсивно(СтрокаУровня_1.Строки,МассивСтрокСУровнями,1,СтруктураСтроки.СведенияПроекта);

    КонецЦикла;

    КонецПроцедуры

    &НаСервере
    Процедура РазложитьДеревоРекурсивно(Строки,МассивСтрокСУровнями,УровеньРодителя,ТекРодитель)

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

    КонецПроцедуры
```