1с: Работа с деревом значений

Задача: создать инструмент для распределения заявок по дням.

Решение: Наиболее удобным вариант я подумал что будет создание некого «дерева», узлами которого будут даты, а «ветвями» — заявки. Заявки можно будет перетаскивать между датами, тем самым равномерно распределяя нагрузку по дням.

Для того чтобы работать с деревьями, в 1С есть специальный тип: Дерево значений. Основной сущностностью у него являются строки. У каждой строки могут быть реквизиты (колонки). В то-же время каждая строка может иметь «потомков» — другие строки.

Создадим на форме «ДеревоОтключений» с типом «Дерево значений», и добавим у него реквизиты:

И перетащим его на форму. Далее по событию открытия, заполним дерево:

ДО = РеквизитФормыВЗначение("ДеревоОтключений");
	ДО.Строки.Очистить();
	
   	Для Счетчик = 0 По Число(Сред(КонецМесяца(объект.ПериодОтключения), 1, 2)) Цикл
    	УДеньМесяца=ДО.Строки.Добавить();
		если Счетчик=0 тогда
			УДеньМесяца.ДатаОтключения="не распределено";
		иначе	
			УДеньМесяца.ДатаОтключения=Формат(Дата(Год(объект.ПериодОтключения),Месяц(объект.ПериодОтключения),Счетчик),"ДФ=dd.MM.yyyy");						
		конецесли;
		УДеньМесяца.expanded=false;
		кол=0;
		для каждого стр из МассивОтключаемых[Счетчик] цикл
			ссср=УДеньМесяца.Строки.Добавить();
			ссср.Отключаемый=стр;
			ссср.ЛС=Строка(стр.ЛС);
			ссср.Адрес=стр.АдресПотребителя;
			кол=кол+1;
		конеццикла;			
		если кол>0 тогда
			УДеньМесяца.ЛС=Строка(кол);
		конецесли;
		
		
    КонецЦикла;

	ЗначениеВРеквизитФормы(ДО,"ДеревоОтключений");

Получаем такую чудную картинку:

Теперь осталось только запретить перетаскивание во все колонки кроме «ДатаОтключения», чтобы избежать «не правильных» деревьев. Для этого заполним событие «ПриПеретаскивании»:

&НаКлиенте
Процедура ДеревоОтключенийПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Поле)
//запретим если имя колонки куда тащим отличается от "ДатаОтключения"
	если Поле.Имя<>"ДеревоОтключенийДатаОтключения" тогда
		СтандартнаяОбработка=ложь;
	конецесли;	                            
//запретим если дата отключения пустая
	Куда=ДеревоОтключений.НайтиПоИдентификатору(Строка);
	если Куда.ДатаОтключения="" тогда
		СтандартнаяОбработка=ложь;
	конецесли;	
//запретим перетаскивание "в корень"
	если Куда.ДатаОтключения=ДеревоОтключений.НайтиПоИдентификатору(Элементы.ДеревоОтключений.ТекущаяСтрока).ПолучитьРодителя().ДатаОтключения тогда
		СтандартнаяОбработка=ложь;
	конецесли;	
КонецПроцедуры

Для того чтобы обновить цифру с количеством «веток» в каждом узле, реализовал нечто подобное, разместив в событии «ОкончаниеПеретаскивания»:

&НаКлиенте
Процедура ДеревоОтключенийОкончаниеПеретаскивания(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка)
	ОбновляюКоличествоЛС();	
КонецПроцедуры

&НаКлиенте
Функция ОбновляюКоличествоЛС()
	 ЭлементыДерева = ДеревоОтключений.ПолучитьЭлементы();	
	 для каждого стр из ЭлементыДерева цикл
		 клв=стр.ПолучитьЭлементы().Количество();
		 если клв<50 тогда
	 		стр.ЛС=клв;
		 конецесли;
	 конеццикла;	 
КонецФункции

В рекруссию не пошел, т.к. в моём случае заведомо известно, что ветвей не более 1

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.