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

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

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



