![]() |
![]() |
![]() |
|
Рекурсивное заполнение элементов иерархического справчника | ☑ | ||
---|---|---|---|---|
0
mmmstr
05.11.08
✎
22:00
|
вопрос: как реализовать с помощью рекурсии заполнение 6-ти уровневого справочника. при чем атрибут, требующий заполнения, текстовый и имеет следующий формат: например для элемента первого уровня: 01.00.00.00.00.00
|
|||
1
mmmstr
05.11.08
✎
22:00
|
так вас устроит, господа?
|
|||
2
Привратник
05.11.08
✎
22:03
|
Процедура Рекурсия(Род)
ТМЦ=СоздатьОбъект("Справочник.Номенклатура"); ТМЦ.использоватьРодителя(Род); тмц.ВыбратьЭлементы(); Пока ТМЦ.ПолучитьЭлемент()=1 Цикл Если ТМЦ.Родитель=Род Тогда Если ТМЦ.ЭтоГруппа()=1 Тогда Рекурсия(ТМЦ.ТекущийЭлемент()); Иначе ПроставитьРеквизит(ТМЦ.ТекущийЭлемент()); КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры Процедура Сформировать() Рекурсия(ПолучитьПустоеЗначение("Справочник.Номенклатура")); КонецПроцедуры // примерно так, правда отбор по родителю весьма неоптимален |
|||
3
mmmstr
05.11.08
✎
22:04
|
то есть все-таки в любом случае цикл по всем элементам справочника?... понятно. спаисбо. именно этот вопрос меня и интересовал.
|
|||
4
vde69
05.11.08
✎
22:07
|
функция РасчитатьРеквизит(эл);
Результат = ""; Если ПустоеЗначение(эл.Родитель)=0 Тогда Результат = Результат + "." + РасчитатьРеквизит(эл); Иначе Результат = эл.Код; КонецЕсли; Возврат Результат; КонецФункции; спр = СоздатьОбъект("Справочник.х"); спр.ВыюратьЭлементы(); Пока спр.получитьЭлемент() = 1 Цикл спр.Реквизит = РасчитатьРеквизит(Спр.ТекущийЭлемент()); спр.Записать(); КонецЦикла; писал с листа, без проверки |
|||
5
Ковычки
05.11.08
✎
22:08
|
(3) можно без цикла, но все равно это цикл
|
|||
6
Дядя Васька
05.11.08
✎
22:10
|
Если ПустоеЗначение(эл.Родитель)=0 Тогда
Результат = РасчитатьРеквизит(эл)+ "." + Результат; // здесь скорее так Иначе Результат = эл.Код; // а это кто такой? КонецЕсли; Если я правильно понял, надо замутить что-то типа код в пределах подчинения, только вместо подчинения родитель, и кодов вообще нет никаких (или есть но левые), и все нужные надо рассчитать... |
|||
7
mmmstr
05.11.08
✎
22:11
|
vde69, какое решение интересное! попробую сейчас!
|
|||
8
Дядя Васька
05.11.08
✎
22:11
|
(3) Можно не по всем, можно только по первому уровню, а дальше рекурсией нырять. Скорее всего как-то так и надо.
|
|||
9
Дядя Васька
05.11.08
✎
22:12
|
(7) но неправильное ))
|
|||
10
mmmstr
05.11.08
✎
22:12
|
если с праками дядюшки, то рекурсии тут нет
|
|||
11
vde69
05.11.08
✎
22:14
|
(9) по оптимальности надо дерево обходить, но там придеться записывать в транкзации по веткам, а (0) вероятно требуеться для разовой обработки! по этому я и предложил более читабельный и простой (но не оптимальный по скорости) вариант
|
|||
12
mmmstr
05.11.08
✎
22:16
|
Процедура ЗаполнитьЭлементы(Уровень,ТекЭлем)
//вот тут и встряла, потому что первый же элемент, который сюда передается - родитель - 0 ЗаполнитьЭлементы(Уровень+1,ТекЭлем?????); КонецПроцедуры Процедура Сформировать() спр = создатьОбъект("Справочник.Материалы"); инк=0; спр.ВыбратьЭлементы(); Пока Спр.ПолучитьЭлемент()>0 Цикл Уровень = спр.текущийЭлемент().Уровень(); Если спр.ТекущийЭлемент().Уровень()=1 Тогда инк=инк+1; спр.УстановитьАтрибут("Шрифт","0"+Строка(Инк)+".00.00.00.00"); спр.записать(); конецЕсли; ЗаполнитьЭлементы(Уровень, спр.текущийЭлемент()); КонецЦикла; КонецПроцедуры |
|||
13
vde69
05.11.08
✎
22:16
|
можно вообще в 2 строки все сделать
1 строка получить волный код 2 строка замена разделителей на память синтаксис не помню а клюшек под рукой нету |
|||
14
Ковычки
05.11.08
✎
22:18
|
все в одной процедуре, без циклов
|
|||
15
Ковычки
05.11.08
✎
22:18
|
рекурсивной процедуре
|
|||
16
mmmstr
05.11.08
✎
22:19
|
да дело втом, что нет кода то! эта разовая обработка и должна заполнить поле Шифр во всех элементах справочника. надо из первого уровня доставать остальные - но как?
|
|||
17
Дядя Васька
05.11.08
✎
22:20
|
(13) Это институтская задачка, нужна именно рекурсия.
|
|||
18
mmmstr
05.11.08
✎
22:20
|
нужна именно рекурсия
|
|||
19
Привратник
05.11.08
✎
22:24
|
(12)Первый цикл не по всем элементам, а только по неимеющим родителя - элементам и группам верхнего уровня. Далее берем группы верхнего уровня и для каждой смотрим подчиненные ей группы и элементы. Для элементов считаем реквизит, группы передаем снова в рекурсию. В (2) не цикл по всем элементам справочника, а отбор элементов справочника, имеющих определенного родителя.
|
|||
20
mmmstr
05.11.08
✎
22:29
|
согласна, что первый цикл только по неимеющим родителям. как посмотреть подчиненные группе элементы, т оесть нижние?
|
|||
21
vde69
05.11.08
✎
22:43
|
20 еще не сделала?
перем сп; функция РасчитатьРеквизит(эл); ТекЗнач = сп.ПолучитьЗначение(эл.Уровень()) + 1; Результат = ТекЗнач; Если ПустоеЗначение(эл.Родитель)=0 Тогда Результат = РасчитатьРеквизит(эл)+ "." + Результат; КонецЕсли; сп.УстановитьЗначение(эл.Уровень(), ТекЗнач); Возврат Результат; КонецФункции; Процедура КнопкаВыполнитьНажатие(Кнопка) сп = СоздатьОбъект("СписокЗначений"); сп.УдалитьВсе(); спр = СоздатьОбъект("Справочник.х"); спр.ВыбратьЭлементы(); Пока спр.получитьЭлемент() = 1 Цикл спр.Код = РасчитатьРеквизит(Спр.ТекущийЭлемент()); КонецЦикла; КонецПроцедуры |
|||
22
Ковычки
05.11.08
✎
22:49
|
вот вам и вся рекурсия ))))
|
|||
23
mmmstr
05.11.08
✎
22:53
|
ТекЗнач = сп.ПолучитьЗначение(эл.Уровень()) + 1;
тут постоянно пусто. это раз. второе: Если ПустоеЗначение(эл.Родитель)=0 Тогда - вот тут сразу же зарубается и все - Шифр мой пустой |
|||
24
Дядя Васька
05.11.08
✎
22:54
|
Да не то это все... Держи, отлажено:
Перем ВсегоУровней; Процедура НумеруемПодгруппу(Родитель="", КодРодителя=0) Спр=СоздатьОбъект("Справочник.ТвойСправочник"); Если ПустоеЗначение(Родитель)=0 Тогда Спр.ИспользоватьРодителя(Родитель.ТекущийЭлемент()); КонецЕсли; Сч=0; Спр.ВыбратьЭлементы(); Пока Спр.ПолучитьЭлемент(0)=1 Цикл Сообщить(Спр.ТекущийЭлемент()); Сч=Сч+1; КодЭлемента=Лев(КодРодителя, (Спр.Уровень()-1)*4); КодЭлемента=КодЭлемента+Формат(Сч,"Ч(0)3"); СчУровней=0; Для СчУровней=Спр.Уровень()+1 По ВсегоУровней Цикл КодЭлемента=КодЭлемента+".000" КонецЦикла; Сообщить(КодЭлемента); Если Спр.ЭтоГруппа()=1 Тогда НумеруемПодгруппу(Спр.ТекущийЭлемент(), КодЭлемента); КонецЕсли; КонецЦикла; КонецПроцедуры Процедура Сформировать() НумеруемПодгруппу() КонецПроцедуры ВсегоУровней=6; |
|||
25
Дядя Васька
05.11.08
✎
22:55
|
+(24) Ну вместо Сообщить() там просто присвоение поставь, и Записать() добавь..
|
|||
26
sam_sam
05.11.08
✎
22:55
|
(22) лучше всех, тока список зачем? ей же не это надо. или это как пример?
|
|||
27
mmmstr
05.11.08
✎
22:58
|
ага список не нужен, его можно использовать, когда без рекукрсии - стэк своеобразный. сейчас, дядюшка, посомтрю:)
|
|||
28
mmmstr
05.11.08
✎
22:59
|
Если ПустоеЗначение(Родитель)=0 Тогда
Спр.ИспользоватьРодителя(Родитель.ТекущийЭлемент()); КонецЕсли; - даа! во тут нет косорезика! ай ,да Василий! |
|||
29
mmmstr
05.11.08
✎
23:05
|
спасибо!
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |