gifts2017

Элемент управления "Дерево" штатными средствами платформы 1С:Предприятие 7.7

Опубликовал Олег Чалаев (OlegTor) в раздел Программирование - Практика программирования

В практике программиста часто возникают задачи, требующие специфической формы представления информации конечному пользователю. В качестве основных требований можно выделить следующие:
1. Информативность.
2. Наглядность.
3. Эргономичность.

Эти и многие другие задачи легко решить, представив некую информацию в структурированном древовидном виде.

Тому, как средствами платформы 1С:Предприятие 7.7 обеспечить такую возможность и посвящена данная статья.
Итак, приступим...

Для того, чтобы пользователь "увидел" дерево и смог управлять им необходимо решить следующие задачи:

1. Определить структуру хранения дерева в оперативной памяти.
2. Обеспечить механизм программного формирования дерева.
3. Реализовать алгоритм визуализации дерева.
4. Предоставить пользователю возмодность управлять деревом.

Начнем по порядку.

Структура хранения дерева в оперативной памяти и его программное формирование.

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

Задачу хранения дерева предлагается решить с помощью хорошо известного объекта платформы СписокЗначений.

Узел - это элемент списка значений, обладающий следующими атрибутами:
1. Идентификатор. Предназначен для именованного доступа к данным узла.
2. Представление. Видимое пользователю строковое представление узла.
3. Значение. Любое значение, хранимое в узле.
4. Знак. Определяет развернута или свернута ветка, определяемая данным узлом.
5. СписокУзлов. Список подчиненных узлов.
6. Родитель. Родительский узел.

Таким образом можно определить следующую функцию позволяющую максимально упростить процесс программного формирования дерева.

Функция ДобавитьУзел(Родитель,Идентификатор,Представление,Значение,Знак = "")
	Узел = СоздатьОбъект("СписокЗначений");
	
	Узел.ДобавитьЗначение(Родитель,"Родитель");
	Узел.ДобавитьЗначение(Идентификатор,"Идентификатор");
	Узел.ДобавитьЗначение(Представление,"Представление");
	Узел.ДобавитьЗначение(Значение,"Значение");
	Узел.ДобавитьЗначение(Знак,"Знак");
	
	Узел.ДобавитьЗначение(СоздатьОбъект("СписокЗначений"),"СписокУзлов");
	
	Если ПустоеЗначение(Родитель) = 0 Тогда
		СписокУзловРодителя = Родитель.Получить("СписокУзлов");
		СписокУзловРодителя.ДобавитьЗначение(Узел,Идентификатор);
		
	КонецЕсли;
		
	Возврат Узел;
КонецФункции


Функция возвращает вновь созданный узел.

Визуализация дерева.

Наибольшими изобразительными способностями среди доступных на платформе 1С:Предприятие 7.7 обладает объект Таблица. Вот с помощью данного объекта и будем визуализировать Наше дерево.

Приведем текст процедур визуализации дерева.

//Рекурсивная процедура визуализации дерева
Процедура ВывестиДерево(Знач Дерево, Уровень)
	Если Уровень > 0 Тогда
		Таблица.ВывестиСекцию("Пустая|Знак");
		
		Для СчУровней = 1 По Уровень - 1 Цикл
			Таблица.ПрисоединитьСекцию("Пустая|Знак");
		КонецЦикла;
	КонецЕсли;
	
	СписокУзлов = Дерево.Получить("СписокУзлов");
	КолУзлов = СписокУзлов.РазмерСписка();
	
	ID_Узла = ID_Узла + 1;
	СписокID.ДобавитьЗначение(Дерево,Строка(ID_Узла));
	
	ПредставлениеУзла = Дерево.Получить("Представление");
	
	Знак = Дерево.Получить("Знак");
	
	Если ПустоеЗначение(Знак) = 0 Тогда
		Если Уровень = 0 Тогда
			Таблица.ВывестиСекцию("Элемент|Знак");
		Иначе
			Таблица.ПрисоединитьСекцию("Элемент|Знак");
		КонецЕсли;
	Иначе
		Таблица.ПрисоединитьСекцию("Пустая|Знак");
	КонецЕсли;
	
	Таблица.ПрисоединитьСекцию("Элемент|Представление");
	
	Если Знак = "-" Тогда
		
		Уровень = Уровень + 1;
		
		Для Сч = 1 По КолУзлов Цикл
			Дерево = СписокУзлов.ПолучитьЗначение(Сч);
			ВывестиДерево(Дерево,Уровень);
		КонецЦикла;
		
		Уровень = Уровень - 1;
	КонецЕсли;
КонецПроцедуры

Процедура СформироватьТаблицу(Номер)
	Таблица.Очистить();
	
	СписокID.УдалитьВсе();
	ID_Узла = 0;
			
	ВывестиДерево(Дерево,0);
		
	Таблица.Показать();
КонецПроцедуры


Стоит особо отметить переменные СписокID и ID_Узла. Эти переменные должны быть глобальными по отношению к модулю обработки.

СписокID - список уникальных сквозных номеров узлов для данного состояния дерева, то есть для данной комбинации свернутых и развернутых узлов. Список номеров очищается и заполняется каждый раз при вызуализации дерева.

ID_Узла используется в качестве расшифровки ячейки, содержащей представление данного узла. Данный прием был избран потому, что использовать в качестве расшифровки непосредственно ссылку на узел невозможно - это приводит к ошибке.

ID_Узла используется для доступа к данным узла в процедуре управления деревом.

Управление деревом.

Процедура ПолучитьКомпонентыАдресаЯчейки(Адрес, НомерСтроки, НомерКолонки)
	НомерСтроки  = Число(Сред(Адрес, Найти(Адрес, "R") + 1));
	НомерКолонки = Число(Сред(Адрес, Найти(Адрес, "C") + 1));
КонецПроцедуры

Процедура ОбработкаЯчейкиТаблицы(Значение,ФлагСтандОбраб,Таблица,Адрес)
      НомерСтроки = 0;
	НомерКолонки = 0;
	ПолучитьКомпонентыАдресаЯчейки(Адрес, НомерСтроки, НомерКолонки); 
	
	Если (Значение = "+") ИЛИ (Значение = "-") Тогда
		ID = Строка(Таблица.Область(НомерСтроки,НомерКолонки + 2).Расшифровка());
		Узел = СписокID.Получить(ID);
		
		
		НовыйЗнак = ?(Значение = "+", "-","+");
			
		Узел.Установить("Знак",НовыйЗнак);
			
		СформироватьТаблицу(Дерево);
	КонецЕсли;		
КонецПроцедуры


Следует отметить, что переменная Дерево является глобальной в контексте данной обработки и представляет собой список значений, являющийся корневым узлом дерева.

В качестве примера можно посмотреть мою разработку
http://infostart.ru/profile/1999/projects/442

Пользуйтесь...

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Олег Чалаев (OlegTor) 04.09.06 17:38
Смотрим, комментируем, высказываем пожелания и рейтинг плюсуем.
2. Maniac (Eugeneer) 04.09.06 21:10
Гораздо красивее и проще ИМХО все делать с помощью внешних компонент. Это уже старинка.
3. Олег Чалаев (OlegTor) 05.09.06 09:53
2 Maniac.
Согласен, красивее - это звучит объективно. Но вот насчет простоты - дело субъективное. Каждый сам решает, что ему проще, а что нет. Не любой программист будет связываться с внешними компонентами. Особенно это относится к тем, кто кроме 1С никаким инструментом не владеет.
4. Сhe Burashka (CheBurator) 05.09.06 12:15
Было бы замечательно, если бы автор выложил в качестве примера не свою обработку, а вариант типовой обработки в ТиС "Дерево документов" (структура подчиненности).
ЗЫ: Удалось ли решить проблему отрисовки таблицы не всей при свертке/развертке, а "сдвигом" секций?
5. Олег Чалаев (OlegTor) 05.09.06 12:37
На "Дерево документов" пока нет времени.
По той же причине решением проблемы оптимизации визуализации дерева пока не занимался.
6. АЛьФ (АЛьФ) 05.09.06 15:28
Пара скриншотов не помешала бы...
7. Сhe Burashka (CheBurator) 05.09.06 19:41
Альф, а можно как-то считать область таблицы и вывести ее допустим на 5 строк ниже и на 2 столбца левее не поячеечно, а типа "куском"? было бы ок... допустим кликаем на роазворот узла - перед выводом всегда можно постиать сколько строк займет - всеь вывод от этого узла все что ниже сдвигаем на это кол-во строк а в свободное место выводим данные узла... типа так....
или не стоит заморачиваться?
8. Сhe Burashka (CheBurator) 05.09.06 19:42
Да, +1 обработку смотрел, понравилось...
Надо xltkfnm чтоб узлы были с разворотом по горизонтали и вертикали - типа как у "новейшего отчета"
9. -=Al=- 06.09.06 03:39
Для меня более привлекательным оказалось использование ТаблицыЗначений вместо списка. Отлично смотрится на форме и более производительно.

2Maniac: Избавте меня от таскания всяких-там компонент по машинам пользователей.
Мне понравилась чья-то фраза: "Ограниченноясть языка 1С - в ограниченности разроботчика".
10. Maniac (Eugeneer) 06.09.06 15:09
гыыы. Ребята не нужно так к компонентам категорично относится. Это раз. Во вторых компоненты не просто создабы шобы были. Это есть то что во многих случаях является спасением и необходимостью первой величины. А насчет таскания и прочего - все от кривости рук зависит.
11. Александр Орефков (orefkov) 07.09.06 14:11
> Избавте меня от таскания всяких-там компонент по машинам пользователей.
КаталогИБ не напрягает таскать?
12. Сhe Burashka (CheBurator) 07.09.06 16:50
13. kairat primbetov (karat60) 07.09.06 19:57
+1, на первый взгляд весьма привлекательно - дальше покажет жизнь
14. Сheckpoint (Natalia) 01.05.09 22:38
Спасибо за идею и красивую реализацию.
Пару раз уже успела позаимствовать в разных разработках.
Например, полуфабрикатное производство.
Конструкторы сначала "пищали от восторга" - потому что красиво,
а потом "схватились за головы" - потому что наглядно увидели свои недочеты ))
15. as108 (AS108) 19.07.09 02:57
Спасибо за ваши труды! Успехов!
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа