ТЗ в Дерево значений с иерархией

1. Shecurok 02.07.24 15:15 Сейчас в теме
Всем привет.
Конфигурация БП 3.0

Есть немного нетривиальная (для меня) задача.

Из ТЗ сделать дерево значений.

ТЗ (собирается запросом из РС) в следующем виде:

Организация | Пользователь | Раздел | Дата

Необходимо получить следующее:

Организация1
Пользователь1
Раздел1 Дата
Пользователь2
Раздел1 Дата
Раздел2 Дата
Организация2
Пользователь1
Раздел2 Дата
Пользователь2
Раздел1 Дата
Раздел2 Дата

Надеюсь понятно.

Пока тестирую на внешней обработке, получается фигня, выходит у меня все равно не в иерархии, а просто перечислением.

Как вообще делать эту самую иерархию?

Сейчас код следующий:
&НаСервере
Процедура ЗаполнитьДеревоНаСервере()
	
   Запрос = Новый Запрос;
   Запрос.Текст = 
   "ВЫБРАТЬ
   |	ДатыЗапретаИзменения.Объект КАК Организация,
   |	ДатыЗапретаИзменения.Пользователь КАК Пользователь,
   |	ДатыЗапретаИзменения.Раздел КАК РазделДатыЗапрета,
   |	ДатыЗапретаИзменения.ДатаЗапрета КАК ДатаЗапрета
   |ИЗ
   |	РегистрСведений.ДатыЗапретаИзменения КАК ДатыЗапретаИзменения"; 
   
   ТЗ = Запрос.Выполнить().Выгрузить();

   Дерево = ВыгрузитьТаблицуЗначенийВДеревоЗначений(ТЗ, "Организация", "Пользователь");

   ЗначениеВРеквизитФормы(Дерево, "ДеревоЗначенийДатыЗапрета");
   
КонецПроцедуры

Функция ВыгрузитьТаблицуЗначенийВДеревоЗначений(Таблица, КлючСтроки = "КлючСтроки", КлючСвязи = "КлючСвязи") Экспорт

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

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

Показать
По теме из базы знаний
Найденные решения
5. SlavaKron 02.07.24 15:48 Сейчас в теме
(1)
&НаСервере
Процедура ЗаполнитьДеревоНаСервере()
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|    ДатыЗапретаИзменения.Объект КАК Организация,
	|    ДатыЗапретаИзменения.Пользователь КАК Пользователь,
	|    ДатыЗапретаИзменения.Раздел КАК РазделДатыЗапрета,
	|    ДатыЗапретаИзменения.ДатаЗапрета КАК ДатаЗапрета
	|ИЗ
	|    РегистрСведений.ДатыЗапретаИзменения КАК ДатыЗапретаИзменения"; 
	
	ТЗ = Запрос.Выполнить().Выгрузить();
	
	ТЗ_Организации = ТЗ.Скопировать(, "Организация");
	ТЗ_Организации.Свернуть("Организация");
	
	Дерево = Новый ДеревоЗначений;
	
	ОписаниеОрганизации = Новый ОписаниеТипов("СправочникСсылка.Организации");
	ОписаниеПользователя = Новый ОписаниеТипов("СправочникСсылка.Пользователи");
	ОписаниеРаздела = Новый ОписаниеТипов("ПланВидовХарактеристикСсылка.РазделыДатЗапретаИзменения");
	ОписаниеДаты = Новый ОписаниеТипов("Дата");
	
	Дерево.Колонки.Добавить("Организация", ОписаниеОрганизации);
	Дерево.Колонки.Добавить("Пользователь", ОписаниеПользователя);
	Дерево.Колонки.Добавить("РазделДатыЗапрета", ОписаниеРаздела);
	Дерево.Колонки.Добавить("ДатаЗапрета", ОписаниеДаты);
	
	СтрокиДерева = Дерево.Строки;
	
	Для Каждого СтрОрг Из ТЗ_Организации Цикл
		УзелОрганизация = Дерево.Строки.Добавить();
		УзелОрганизация.Организация = СтрОрг.Организация;
		
		СтрокиОрганизации = ТЗ.Скопировать(Новый Структура("Организация", СтрОрг.Организация));
		ТЗ_Пользователи = СтрокиОрганизации.Скопировать(, "Пользователь");
		ТЗ_Пользователи.Свернуть("Пользователь");
		Для Каждого СтрП Из ТЗ_Пользователи Цикл
			УзелПользователь = УзелОрганизация.Строки.Добавить();
			УзелПользователь.Организация = СтрОрг.Организация;
			УзелПользователь.Пользователь = СтрП.Пользователь;
			СтрокиПользователя = СтрокиОрганизации.Скопировать(Новый Структура("Пользователь", СтрП.Пользователь));
			Для Каждого Стр Из СтрокиПользователя Цикл
				НоваяСтрока = УзелПользователь.Строки.Добавить();
				ЗаполнитьЗначенияСвойств(НоваяСтрока, Стр);
			КонецЦикла;
		КонецЦикла;
	КонецЦикла;
	
	ЗначениеВРеквизитФормы(Дерево, "ДеревоЗначенийДатыЗапрета");
	
КонецПроцедуры
Показать
Shecurok; +1 Ответить
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
5. SlavaKron 02.07.24 15:48 Сейчас в теме
(1)
&НаСервере
Процедура ЗаполнитьДеревоНаСервере()
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|    ДатыЗапретаИзменения.Объект КАК Организация,
	|    ДатыЗапретаИзменения.Пользователь КАК Пользователь,
	|    ДатыЗапретаИзменения.Раздел КАК РазделДатыЗапрета,
	|    ДатыЗапретаИзменения.ДатаЗапрета КАК ДатаЗапрета
	|ИЗ
	|    РегистрСведений.ДатыЗапретаИзменения КАК ДатыЗапретаИзменения"; 
	
	ТЗ = Запрос.Выполнить().Выгрузить();
	
	ТЗ_Организации = ТЗ.Скопировать(, "Организация");
	ТЗ_Организации.Свернуть("Организация");
	
	Дерево = Новый ДеревоЗначений;
	
	ОписаниеОрганизации = Новый ОписаниеТипов("СправочникСсылка.Организации");
	ОписаниеПользователя = Новый ОписаниеТипов("СправочникСсылка.Пользователи");
	ОписаниеРаздела = Новый ОписаниеТипов("ПланВидовХарактеристикСсылка.РазделыДатЗапретаИзменения");
	ОписаниеДаты = Новый ОписаниеТипов("Дата");
	
	Дерево.Колонки.Добавить("Организация", ОписаниеОрганизации);
	Дерево.Колонки.Добавить("Пользователь", ОписаниеПользователя);
	Дерево.Колонки.Добавить("РазделДатыЗапрета", ОписаниеРаздела);
	Дерево.Колонки.Добавить("ДатаЗапрета", ОписаниеДаты);
	
	СтрокиДерева = Дерево.Строки;
	
	Для Каждого СтрОрг Из ТЗ_Организации Цикл
		УзелОрганизация = Дерево.Строки.Добавить();
		УзелОрганизация.Организация = СтрОрг.Организация;
		
		СтрокиОрганизации = ТЗ.Скопировать(Новый Структура("Организация", СтрОрг.Организация));
		ТЗ_Пользователи = СтрокиОрганизации.Скопировать(, "Пользователь");
		ТЗ_Пользователи.Свернуть("Пользователь");
		Для Каждого СтрП Из ТЗ_Пользователи Цикл
			УзелПользователь = УзелОрганизация.Строки.Добавить();
			УзелПользователь.Организация = СтрОрг.Организация;
			УзелПользователь.Пользователь = СтрП.Пользователь;
			СтрокиПользователя = СтрокиОрганизации.Скопировать(Новый Структура("Пользователь", СтрП.Пользователь));
			Для Каждого Стр Из СтрокиПользователя Цикл
				НоваяСтрока = УзелПользователь.Строки.Добавить();
				ЗаполнитьЗначенияСвойств(НоваяСтрока, Стр);
			КонецЦикла;
		КонецЦикла;
	КонецЦикла;
	
	ЗначениеВРеквизитФормы(Дерево, "ДеревоЗначенийДатыЗапрета");
	
КонецПроцедуры
Показать
Shecurok; +1 Ответить
6. Shecurok 02.07.24 15:51 Сейчас в теме
10. Shecurok 04.07.24 16:11 Сейчас в теме
(5) Не хочу создавать новую тему, может тут подскажите с еще одним моментом.

Дерево у меня выведено, спасибо Вам.

Как мне написать при изменении таблицы (ну даже не изменении, а, допустим, запись нового элемента) - была собственно запись в РС?

В событии после редактирования можно работать только в "клиенте", там собственно особо не развернешься. На "сервер" передать Элемент.ТекущиеДанные не могу. Как вообще такие вещи реализуются?

Может выгрузить данные в массив и его уже передать на сервер? Или как лучше?
11. SlavaKron 04.07.24 17:37 Сейчас в теме
(10) Вот в таком виде, с точки зрения пользователя, было бы удобно иметь кнопку "Сохранить" или "Записать" изменения, вместо динамического сохранения в РС. Пользователям не очень комфортно, когда интерактивное изменение в поле ввода сразу же ведёт к изменению в ИБ. Для реализации в дереве необходима еще одна служебная колонка: флаг, указывающий, что в данной строке были сделаны изменения. По нажатию кнопки "Записать изменения", делаем контекстный серверный вызов, обходим дерево, проверяем флаг: если включен – записываем в РС.
Измененные строки можно даже подкрасить через условное оформления для наглядности, чтобы было видно, что изменено.
Shecurok; +1 Ответить
12. Shecurok 08.07.24 10:27 Сейчас в теме
(11) Сделал как Вы и посоветовали - все круто, спасибо большое)
13. Shecurok 10.07.24 15:00 Сейчас в теме
(5) а есть возможность при выводе дерева значений (при раскрытии списка) - "родителя" не выводить.

Ну т.е. как сейчас:

-Организация1
- Организация1 Пользователь1
- Организация1 Пользователь1 Раздел 1
- Организация1 Пользователь2
- Организация1 Пользователь2 Раздел 1
-Организация2
- Организация2 Пользователь1
- Организация1 Пользователь1 Раздел 1
- Организация2 Пользователь2
- Организация1 Пользователь2 Раздел 1


Хотелось бы видеть

-Организация1
- Пользователь1
- Раздел 1
- Пользователь2
- Раздел 1

Чет не могу найти как убирается
14. user2033930 10.07.24 15:10 Сейчас в теме
(13) Никак не убирается. Делать одну колонку и самостоятельно заполнять её на разных уровнях разными значениями.
15. Shecurok 10.07.24 15:21 Сейчас в теме
2. user1706813 02.07.24 15:35 Сейчас в теме
Может быть как вариант решения?

Процедура СформироватьДеревоЗначений()
    // Запрос для получения данных из регистра сведений
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |   РегистрыСведений.НазваниеРегистра.Организация КАК Организация,
    |   РегистрыСведений.НазваниеРегистра.Пользователь КАК Пользователь,
    |   РегистрыСведений.НазваниеРегистра.Раздел КАК Раздел,
    |   РегистрыСведений.НазваниеРегистра.Дата КАК Дата
    |ИЗ
    |   РегистрыСведений.НазваниеРегистра КАК РегистрыСведений.НазваниеРегистра";

    ТаблицаЗначений = Запрос.Выполнить().Выгрузить();

    // Создание дерева значений
    Дерево = Новый ДеревоЗначений;
    Дерево.Колонки.Добавить("Наименование");
    Дерево.Колонки.Добавить("Дата");

    // Заполнение дерева значений на основе таблицы значений
    Для Каждого СтрокаОрганизация Из ТаблицаЗначений.Сгруппировать("Организация") Цикл
        УзелОрганизация = Дерево.Строки.Добавить();
        УзелОрганизация.Наименование = СтрокаОрганизация.Организация;

        ТаблицаПользователи = ТаблицаЗначений.НайтиСтроки(Новый Структура("Организация", СтрокаОрганизация.Организация));
        Для Каждого СтрокаПользователь Из ТаблицаПользователи.Сгруппировать("Пользователь") Цикл
            УзелПользователь = УзелОрганизация.Строки.Добавить();
            УзелПользователь.Наименование = СтрокаПользователь.Пользователь;

            ТаблицаРазделы = ТаблицаПользователи.НайтиСтроки(Новый Структура("Пользователь", СтрокаПользователь.Пользователь));
            Для Каждого СтрокаРаздел Из ТаблицаРазделы Цикл
                УзелРаздел = УзелПользователь.Строки.Добавить();
                УзелРаздел.Наименование = СтрокаРаздел.Раздел;
                УзелРаздел.Дата = СтрокаРаздел.Дата;
            КонецЦикла;
        КонецЦикла;
    КонецЦикла;

    // Вывод результата для проверки
    ВывестиДеревоЗначенийВДеревоФормы(Дерево);
КонецПроцедуры

// Вспомогательная процедура для вывода дерева значений на форму (только для проверки)
Процедура ВывестиДеревоЗначенийВДеревоФормы(Дерево)
    Форма = ПолучитьФорму("ОбщаяФорма.ТестоваяФорма");
    Форма.ЭлементыФормы.Дерево.ЗагрузитьДеревоЗначений(Дерево);
    Форма.Открыть();
КонецПроцедуры
Показать
Shecurok; +1 Ответить
4. Shecurok 02.07.24 15:45 Сейчас в теме
(2) Метода сгруппировать нету, свернуть возможно?
3. VmvLer 02.07.24 15:37 Сейчас в теме
Добавить в запрос секцию ИТОГИ ПО,
проверить в консоли запросов результат
и выгрузить ПоГруппировкам в уже готовое дерево.
odinsmot; Shecurok; +2 Ответить
7. Shecurok 02.07.24 15:51 Сейчас в теме
как у вас всех легко и быстро получается) пойду анализировать что надо сделать было
8. user1706813 02.07.24 15:52 Сейчас в теме
9. SlavaKron 02.07.24 15:54 Сейчас в теме
(8) Неплохая попытка для нейронки)
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот