Коллеги, привет.

Есть дерево значений с заранее известной структурой (Категория/ВидПриемаПищи/Блюдо), но неизвестным количеством подчиненных веток.

Требуется сделать так, чтобы на каждом уровне вложенности (кроме верхнего) количество подчиненных веток было одинаковым.

Например, в категориях А и Б нужно, чтобы к-во приемов пищи было одинаковым. К примеру в категории А по факту был только завтрак+обед, в Б -завтрак+обед+ужин. Надо сделать так, чтобы в категории А было 3 подчиненных ветки.

То же касается и следующего уровня вложенности.

В результате параллельные ветки категорий должны стать одинаковыми по количеству веток.
---
Если мы сопоставляем по уровням дерева, вне зависимости от тип приема пищи то нет.

```1c
    МаксимальноеКоличествоПриемовПищи = 0;
    СоответствиеКоличестваИУровней = Новый Соответствие;
    Для Каждого СтрКатегорий из Дерево.Строки Цикл
    КоличествоПриемовПищи = СтрКатегорий.Строки.Количество();
    МаксимальноеКоличествоПриемовПищи = Макс(КоличествоПриемовПищи ,МаксимальноеКоличествоПриемовПищи );
    Для Инд = 0 по КоличествоПриемовПищи -1 Цикл
    СтрПриемовПищи = СтрКатегорий.Строки[Инд];
    КоличествоБлюд = СтрПриемовПищи.Строки.Количество();
    КоличествоВСоответствии = СоответствиеПП [Инд];
    Если КоличествоВСоответствии = Неопределено Тогда
    КоличествоВСоответствии = 0;
    КонецЕсли;
    СоответствиеПП [Инд] = Макс(КоличествоБлюд,КоличествоВСоответствии )
    КонецЦикла;
    КонецЦикла;

    Для Каждого СтрКатегорий из Дерево.Строки Цикл
    КоличествоПриемовПищи = СтрКатегорий.Строки.Количество();
    Пока КоличествоПриемовПищи< МаксимальноеКоличествоПриемовПищи Цикл
    СтрКатегорий.Строки.Добавить();
    КоличествоПриемовПищи = КоличествоПриемовПищи + 1;
    КонецЦикла;
    Для Инд = 0 по КоличествоПриемовПищи -1 Цикл
    СтрПриемовПищи = СтрКатегорий.Строки[Инд];
    КоличествоБлюд = СтрПриемовПищи.Строки.Количество();
    КоличествоВСоответствии = СоответствиеПП [Инд];
    Пока КоличествоБлюд< КоличествоВСоответствии Цикл
    СтрПриемовПищи.Строки.Добавить();
    КоличествоБлюд = КоличествоБлюд + 1;
    КонецЦикла;
    КонецЦикла;
    КонецЦикла;
```
---
Александр, спасибо.

Сделал в два прохода дерева, но немного по другому.

В первый проход получил соответствие количеств
Ключ Значение
Обед 5
Завтрак 4
"ПриемовПищиВКатегории" 2

Во второй проход добил ветки до нужного количества

```1c
    Количество = Новый Соответствие;

    Для Каждого Категория Из СтрокаОрганизации.Строки Цикл

    Ключ = "ПриемовПищиВКатегории";
    ТекущееКоличество = Количество.Получить(Ключ);
    Если ТекущееКоличество = Неопределено Тогда
    ТекущееКоличество = 0;
    КонецЕсли;

    Количество.Вставить(Ключ, Макс(ТекущееКоличество, Категория.Строки.Количество()));

    Для Каждого ПриемПищи Из Категория.Строки Цикл

    Ключ = ПриемПищи.ПриемПищи;
    ТекущееКоличество = Количество.Получить(Ключ);
    Если ТекущееКоличество = Неопределено Тогда
    ТекущееКоличество = 0;
    КонецЕсли;

    Количество.Вставить(Ключ, Макс(ТекущееКоличество, ПриемПищи.Строки.Количество()));

    КонецЦикла;

    КонецЦикла;

    Для Каждого Категория Из СтрокаОрганизации.Строки Цикл

    Ключ = "ПриемовПищиВКатегории";
    ТекущееКоличество = Количество.Получить(Ключ);
    ДополнитьСтроки(Категория, ТекущееКоличество);

    Для Каждого ПриемПищи Из Категория.Строки Цикл

    Ключ = ПриемПищи.ПриемПищи;
    ТекущееКоличество = Количество.Получить(Ключ);
    ДополнитьСтроки(ПриемПищи, ТекущееКоличество);

    КонецЦикла;

    КонецЦикла;
```
---
Показывайте код
---
Кода нет. Два дня впустую ((
---
в общем случае будет что-то вроде такого:

```1c
    ЭлементыДерева1 = Дерево1.ПолучитьЭлементы();
    ЭлементыДерева2 = Дерево2.ПолучитьЭлементы();

    РазницаВКоличестве = ЭлементыДерева1.Количество() - ЭлементыДерева2.Количество();

    Если РазницаВКоличестве > 0 Тогда
    Для Сч = 1 По РазницаВКоличестве Цикл
    ЭлементыДерева2.Добавить();
    КонецЦикла;
    ИначеЕсли РазницаВКоличестве < 0 Тогда
    Для Сч = 1 По -РазницаВКоличестве Цикл
    ЭлементыДерева1.Добавить();
    КонецЦикла;
    КонецЕсли;
```
---
Дерево изначально одно
---
каким образом должно выполнятся разделение на 2 дерева? или разделения нет? категорий(веток дерева первого уровня) может быть сколько угодно?
---
Два дерева и не нужно (как минимум необязательно), можно обойтись одним, главное чтобы количество подчиненных веток было одинаковым.

Категорий пока 2, но в дальнейшем не факт.
---
Один раз обойти дерево и получить соответствие вида "Вид приема пищи" = "максимальное количество блюд".

Далее в цикл на 1 уровень дерева - в нем проверять что в данной категории есть все виды приема пищи из соответствия. Если нет - добавлять. Ну и количество строк по приему пищи добавлять, если меньше.
---
Видов приемов пищи так же может быть разное количество, их так же нужно знать максимальное количество.
Т.е. придется как минимум 2 раза пробежаться по дереву, чтобы узнать максимумы по уровням вложенности.
---
Т.е. придется как минимум 2 раза пробежаться по дереву, чтобы узнать максимумы по уровням вложенности. Можно в процессе добавления строк сохранять фактические максимумы в отдельное соответствие.
---
Да, это будет замечательно, если есть возможность вмешаться в процесс формирования дерева
---
Видов приемов пищи так же может быть разное количество, их так же нужно знать максимальное количество.

Если добавлять все виды приема пищи во все категории, тогда и не важно что где есть.
Если же нельзя добавлять, а надо как то сопоставлять, то вот я как-то даже не знаю.
В одном полдник и ужин в другом завтрак, обед и ужин - с чем сопоставлять полдник?
С завтраком или обедом?
---
так понимаю, сопоставление - не суть, суть - одинаковое количество записей по уровню
---
Ну тогда не вид приема пищи, а уровень в дереве будет ключем.
2 значения надо нам:
1 - максимальное количество уровней в категории
2 - максимальное количество блюд в уровне - для этого соответствие
---
Ну то есть два соответствия: Допустимые максимумы (для ограничения) и Фактические максимумы (для выравнивания)
---
Если мы сопоставляем по уровням дерева, вне зависимости от тип приема пищи то нет.

```1c
    МаксимальноеКоличествоПриемовПищи = 0;
    СоответствиеКоличестваИУровней = Новый Соответствие;
    Для Каждого СтрКатегорий из Дерево.Строки Цикл
    КоличествоПриемовПищи = СтрКатегорий.Строки.Количество();
    МаксимальноеКоличествоПриемовПищи = Макс(КоличествоПриемовПищи ,МаксимальноеКоличествоПриемовПищи );
    Для Инд = 0 по КоличествоПриемовПищи -1 Цикл
    СтрПриемовПищи = СтрКатегорий.Строки[Инд];
    КоличествоБлюд = СтрПриемовПищи.Строки.Количество();
    КоличествоВСоответствии = СоответствиеПП [Инд];
    Если КоличествоВСоответствии = Неопределено Тогда
    КоличествоВСоответствии = 0;
    КонецЕсли;
    СоответствиеПП [Инд] = Макс(КоличествоБлюд,КоличествоВСоответствии )
    КонецЦикла;
    КонецЦикла;

    Для Каждого СтрКатегорий из Дерево.Строки Цикл
    КоличествоПриемовПищи = СтрКатегорий.Строки.Количество();
    Пока КоличествоПриемовПищи< МаксимальноеКоличествоПриемовПищи Цикл
    СтрКатегорий.Строки.Добавить();
    КоличествоПриемовПищи = КоличествоПриемовПищи + 1;
    КонецЦикла;
    Для Инд = 0 по КоличествоПриемовПищи -1 Цикл
    СтрПриемовПищи = СтрКатегорий.Строки[Инд];
    КоличествоБлюд = СтрПриемовПищи.Строки.Количество();
    КоличествоВСоответствии = СоответствиеПП [Инд];
    Пока КоличествоБлюд< КоличествоВСоответствии Цикл
    СтрПриемовПищи.Строки.Добавить();
    КоличествоБлюд = КоличествоБлюд + 1;
    КонецЦикла;
    КонецЦикла;
    КонецЦикла;
```
---
Александр, спасибо.

Сделал в два прохода дерева, но немного по другому.

В первый проход получил соответствие количеств
Ключ Значение
Обед 5
Завтрак 4
"ПриемовПищиВКатегории" 2

Во второй проход добил ветки до нужного количества

```1c
    Количество = Новый Соответствие;

    Для Каждого Категория Из СтрокаОрганизации.Строки Цикл

    Ключ = "ПриемовПищиВКатегории";
    ТекущееКоличество = Количество.Получить(Ключ);
    Если ТекущееКоличество = Неопределено Тогда
    ТекущееКоличество = 0;
    КонецЕсли;

    Количество.Вставить(Ключ, Макс(ТекущееКоличество, Категория.Строки.Количество()));

    Для Каждого ПриемПищи Из Категория.Строки Цикл

    Ключ = ПриемПищи.ПриемПищи;
    ТекущееКоличество = Количество.Получить(Ключ);
    Если ТекущееКоличество = Неопределено Тогда
    ТекущееКоличество = 0;
    КонецЕсли;

    Количество.Вставить(Ключ, Макс(ТекущееКоличество, ПриемПищи.Строки.Количество()));

    КонецЦикла;

    КонецЦикла;

    Для Каждого Категория Из СтрокаОрганизации.Строки Цикл

    Ключ = "ПриемовПищиВКатегории";
    ТекущееКоличество = Количество.Получить(Ключ);
    ДополнитьСтроки(Категория, ТекущееКоличество);

    Для Каждого ПриемПищи Из Категория.Строки Цикл

    Ключ = ПриемПищи.ПриемПищи;
    ТекущееКоличество = Количество.Получить(Ключ);
    ДополнитьСтроки(ПриемПищи, ТекущееКоличество);

    КонецЦикла;

    КонецЦикла;
```
---
Обращайтесь)
---
Обязательно)
---
Примерно так я и думал в начале))

Проблема в том, что при обходе 1-й категории нет прямого доступа ко 2-й.

Пробовал так

```1c
    Строка1 = Дерево.Строки.Получить(0);
    Строка2 = Дерево.Строки.Получить(1);

    Количество = Макс(Строка1.Строки.Количество(), Строка2.Строки.Количество());

    Пока Строка1.Строки.Количество() < Количество Цикл
    Строка1.Строки.Добавить();
    КонецЦикла;
    Пока Строка2.Строки.Количество() < Количество Цикл
    Строка2.Строки.Добавить();
    КонецЦикла;
```

А дальше надо перейти на след. уровень, и тут затык
---
Это решается рекурсией с передачей максимального количества в качестве одно из параметров вызова
либо в процессе формирования дерева, в узлах фиксировать максимальное количество и параметры не нужны.
---
```1c
    СоответствиеПП = Новый Соответствие;
    Для Каждого СтрКатегорий из Дерево.Строки Цикл
    Для Каждого СтрПриемовПищи из СтрКатегорий.Строки Цикл
    КоличествоБлюд = СтрПриемовПищи.Строки.Количество();
    КоличествоВСоответствии = СоответствиеПП [СтрПриемовПищи.ВидПриемаПищи];
    Если КоличествоВСоответствии = Неопределено Тогда
    КоличествоВСоответствии = 0;
    КонецЕсли;
    СоответствиеПП [СтрПриемовПищи.ВидПриемаПищи] = Макс(КоличествоБлюд,КоличествоВСоответствии )
    КонецЦикла;
    КонецЦикла;
```
---
И в чем проблема? Задать колонку "Ограничение", и программно её заполнять из фиасированного соответствия...
При добавлении (формальный синтаксис):
Если РодительскаяСтрока.Количество() > РодительскаяСтрока.Ограничение
Тогда ОтказОтДобавления.
Иначе ТекущаяСтрока.Ограничение = НастройкаУровней.Получить(ТекущаяСтрока.Уровень())

А перед печатью рекурсивно пробежать и добавить пустые строки, добив до максимума...
---
Проблема в том, что обходя рекурсивно дерево, я натыкаюсь на то, что повторно обхожу ветки и начинаю сравнивать то, что уже сравнивал, уходя в бесконечный цикл
---
Сначала подумал "легкотня", однако заходил с разных сторон (копировал дерево в две копии, рекурсивно добавлял строки в исходное дерево) натыкался на бесконечный цикл.
---
Да не сложно так то. смотреть в 10