|
Разузлование: контроль зацикливания в дереве узлов | ☑ | ||
---|---|---|---|---|
0
UtkinPavel
22.11.11
✎
19:47
|
В университете задали решать задачу, связанную с разузлованием. В рамках этой задачи решить проблему зацикливания в дереве узлов.
Дано два справочника "Номенклатура" и "Спецификации". "Номенклатура" - простой справочник без реквизитов, групп, владельцев/подчиненных. "спецификации" - простой справочник с реквизитом "СборочнаяЕдиница" (СправочникСсылка.Номенклатура) и табличной частью "ТЧ" с реквизитами "Компонента" (СправочникСсылка.Номенклатура) и "Количество" (Число). Платформа: 1С 8.2.14.528. Ниже приведено мое решение. Вопрос: существует ли более правильное и менее затратное решение, чем мое? Мое решение Я решил контролировать зацикливание на стадии создания нового элемента в справочнике "Спецификации". Процедура проверки вызывается в процедуре "ПередЗаписью()". а. проблема "А - А" (компонента входит саму в себя) мной решена так. Сначала пользователь вводит сборочную единицу. После ввода это поле блокируется, разблокировывается табличная часть. При выборе компоненты в динамический список формы выбора номенклатуры передается параметр со значением выбранной сборочной единицы - соответственно динамический список формируется без нее. б. проблема "А - ... - А" (компонента входит саму в себя опосредованно) мной решена так. Формируется таблица значений с колонками "сборочная единица" и "компонента". Сначала с помощью разузлования снизу-вверх формируется ветвь узлов, являющихся сборочными единицами для выбранной сборочной единицы и ее сборочных единиц вплоть до самой верхней. Комбинации заносятся в ТЗ. Затем каждый из добавленных в ТЗ компонент разузловывается и комбинации снова заносятся в ТЗ. После этого ТЗ проверяется на наличие повторяющихся записей. Если таковые имеются - значит есть зацикливание. Код: &НаКлиенте Процедура ПередЗаписью(Отказ, ПараметрыЗаписи) Объект.Наименование = Строка(Объект.СборочнаяЕдиница); Отказ = ПроверитьЗацикливание(); КонецПроцедуры &НаСервере Функция ПроверитьЗацикливание() /////////////////////////// //Построение дерева узлов// /////////////////////////// Дерево = Новый ТаблицаЗначений; Дерево.Колонки.Добавить("СборочнаяЕдиница"); Дерево.Колонки.Добавить("Компонента"); ОбратноеРазузлование(Объект.СборочнаяЕдиница, Дерево); Для Каждого ТекущаяСтрока Из Объект.ТЧ Цикл НоваяСтрока = Дерево.Добавить(); НоваяСтрока.СборочнаяЕдиница = Объект.СборочнаяЕдиница; НоваяСтрока.Компонента = ТекущаяСтрока.Компонента; ПрямоеРазузлование(Дерево, ТекущаяСтрока.Компонента); КонецЦикла; //////////////////////////////////////////////// //Проверка наличия зацикливаний в дереве узлов// //////////////////////////////////////////////// КоличествоОшибок = 0; Для Каждого ТекущаяСтрока Из Дерево Цикл Массив = Дерево.НайтиСтроки(Новый Структура("СборочнаяЕдиница, Компонента", ТекущаяСтрока.СборочнаяЕдиница, ТекущаяСтрока.Компонента)); КоличествоОшибок = КоличествоОшибок + Массив.Количество() - 1; КонецЦикла; ////////////////////// //Возврат результата// ////////////////////// Если КоличествоОшибок = 0 Тогда Возврат Ложь; Иначе Сообщить("Обнаружена угроза зацикливания! Пожалуйста, внесите изменения в список компонент."); Возврат Истина; КонецЕсли; КонецФункции &НаСервере Процедура ПрямоеРазузлование(Дерево, Узел) Запрос = Новый Запрос ( "ВЫБРАТЬ | СпецификацииТЧ.Компонента КАК Компонента |ИЗ | Справочник.Спецификации.ТЧ КАК СпецификацииТЧ | ПОЛНОЕ СОЕДИНЕНИЕ Справочник.Спецификации КАК Спецификации | ПО СпецификацииТЧ.Ссылка = Спецификации.Ссылка |ГДЕ | Спецификации.СборочнаяЕдиница = &СборочнаяЕдиница" ); Запрос.УстановитьПараметр("СборочнаяЕдиница", Узел); Результат = Запрос.Выполнить().Выбрать(); Пока Результат.Следующий() Цикл НоваяСтрока = Дерево.Добавить(); НоваяСтрока.СборочнаяЕдиница = Узел; НоваяСтрока.Компонента = Результат.Компонента; ПрямоеРазузлование(Дерево, Результат.Компонента); КонецЦикла; КонецПроцедуры &НаСервере Процедура ОбратноеРазузлование(Узел, Дерево) Запрос = Новый Запрос ( "ВЫБРАТЬ | Спецификации.СборочнаяЕдиница КАК СборочнаяЕдиница |ИЗ | Справочник.Спецификации.ТЧ КАК СпецификацииТЧ | ПОЛНОЕ СОЕДИНЕНИЕ Справочник.Спецификации КАК Спецификации | ПО СпецификацииТЧ.Ссылка = Спецификации.Ссылка |ГДЕ | СпецификацииТЧ.Компонента = &Компонента" ); Запрос.УстановитьПараметр("Компонента", Узел); Результат = Запрос.Выполнить().Выбрать(); Пока Результат.Следующий() Цикл НоваяСтрока = Дерево.Добавить(); НоваяСтрока.СборочнаяЕдиница = Результат.СборочнаяЕдиница; НоваяСтрока.Компонента = Узел; ОбратноеРазузлование(Результат.СборочнаяЕдиница, Дерево); КонецЦикла; КонецПроцедуры |
|||
1
Базис
naïve
22.11.11
✎
19:50
|
Это где сейчас так учат?
|
|||
2
Михаил Козлов
22.11.11
✎
19:53
|
Можно разузловывать не до конца, проверяя при разузловании компоненты вхождение ее компонент в "текущий" список компонент.
|
|||
3
UtkinPavel
22.11.11
✎
20:18
|
"Базис
Это где сейчас так учат?" ННГУ. Пожалуйста, ругайте, критикуйте, советуйте — все приму во внимание. |
|||
4
UtkinPavel
22.11.11
✎
20:23
|
Михаил Козлов: "Можно разузловывать не до конца, проверяя при разузловании компоненты вхождение ее компонент в "текущий" список компонент."
Спасибо! |
|||
5
Armando
22.11.11
✎
20:43
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |