Имя: Пароль:
1C
1С v8
Получить родителя не ниже 2 уровня.
0 Balabass
 
07.11.11
09:21
Если при выборе подразделения, подразделение имеет уровени() = 3, 4 или 5 и более, взять его родителя - не более 2 уровня();
Делаю обход подразделений в ТЗ.

если времПоздразделение.уровень()>1 тогда
строка.дт1 = ПолучитьВерхнегоРодителя(времПоздразделение);
иначе
строка.дт1 = времПоздразделение.код;
конецесли;

Т.е. если подразделение находиться на 2 3 и т.д. уровне - то запускаем функцию ПолучитьВерхнегоРодителя(времПоздразделение);

Функция ПолучитьВерхнегоРодителя(Ссылка)
   
Если не ЗначениеЗаполнено(Ссылка.Родитель) Тогда
    Возврат Ссылка.код; //Оставил на всякий пожарный - это если у подразделения нет родителя.
 Иначе
     Если Ссылка.Родитель.уровень() = 1 тогда
         Возврат Ссылка.код;
     иначе
           ПолучитьВерхнегоРодителя(Ссылка.Родитель);
     КонецЕсли;
 КонецЕсли;
 
КонецФункции

Вот тут вопрос. У меня при проходе данной функции сначало делается  Возврат Ссылка.код; Затем  КонецЕсли;, а потом ПолучитьВерхнегоРодителя(Ссылка.Родитель); сново. Непонятно - почему он так поступает?
Почему не успокаивается, когда 1 раз возвращает результат?
1 Не Печенкин
 
07.11.11
09:27
1. Возврат ПолучитьВерхнегоРодителя(Ссылка.Родитель);
2. Зачем возвращать код, если можно ссылку возвращать?
2 chingiz
 
07.11.11
09:29
(0) это рекурсивная функция. При возврате со второго уровня он как бы возвращается назад до начального уровня...не знаю почему так, тоже интересно было 8) Но все так и должно работать.
3 Мимохожий Однако
 
07.11.11
09:33
Можно использовать полный код и брать из списка второго родителя.
4 Balabass
 
07.11.11
09:33
(1) 1. Если Возврат ПолучитьВерхнегоРодителя(Ссылка.Родитель); - то он 2 раза проходит почему то.
(1) 2. Да мне кобсвенно только код и нужен. )
(2) Да фигню какую то порит. Расчитывает верно, а потом как бы опять возвращает исходный вариант.
5 Balabass
 
07.11.11
09:34
(3) Это как? Програмно получить родителя 2 уровня?
6 Wobland
 
07.11.11
09:37
(5) кури ПолныйКод в СП
7 Fragster
 
гуру
07.11.11
09:37
все-таки 1сники не программисты, да :(
8 Мимохожий Однако
 
07.11.11
09:39
Шаг 1.
ПолныйКод (FullCode)
Синтаксис:

ПолныйКод()
Возвращаемое значение:

Тип: Строка. Строка, включающая код элемента и коды всех вышестоящих элементов.
Коды выводятся слева направо, начиная с самого верхнего уровня, разделяются символом "/".
Описание:

Получает код элемента справочника с учетом кодов всех вышестоящих элементов.

Доступность:

Сервер, толстый клиент, внешнее соединение.
Пример:

Сообщить("Полный код данного элемента: " +
         Объект.ПолныйКод());
9 vmv
 
07.11.11
09:40
рекурсию вбивают в мозг на 1-м курсе в приличном вузе по специальности
10 Мимохожий Однако
 
07.11.11
09:40
Шаг 2. Выделяешь из полученного кода нужного родителя.
11 Wobland
 
07.11.11
09:41
(10) а вот как?
12 Axel2009
 
07.11.11
09:42
нужно
Возврат ПолучитьВерхнегоРодителя(Ссылка.Родитель);
13 vmv
 
07.11.11
09:43
в конце концоа запостят мегатстроку получения родителя по шаблону, в 8.2 работает? не проверял, да и зачем
14 Мимохожий Однако
 
07.11.11
09:43
(11)В каждой типовой конфигурации в общем модуле есть функция типа РазложитьСтроку(строка, разделитель). В данном случае есть разделитель "/"
15 Wobland
 
07.11.11
09:44
(14) код номер раз: "/", код номер два: "//" ;)
16 Мимохожий Однако
 
07.11.11
09:45
(15)Исключения бывают. Для данного случая в 99% подойдет
17 Мимохожий Однако
 
07.11.11
09:46
Есть вариант Объект.Родитель.Родитель через Попытку :-)
18 vmv
 
07.11.11
09:47
(14) если код текстовий и добрая тетя ввела код ЭЛЕМЕНТА 5/10-2/45 просто потому, что так было у клиента - то ваш метод летит в трубу.

получать родителя парсингом это от лукавого, лучше сразу использовать классику и вводить заблудшие души в искушение
19 Мимохожий Однако
 
07.11.11
09:49
(18)Я - не пастор и не учитель. Либо разбирается с рекурсией, либо другие методы. Если важнее универсальность,то - классика. Но судя по задаче, здесь классика не обязательна.
20 vmv
 
07.11.11
09:49
да запросом,блин, ИТОГИ ПО если всех вышестоящих или просая пузырьковая рекурсия без лишних условий и проверок как в сабже - все
21 Мимохожий Однако
 
07.11.11
09:50
(20)Дай автору код для полного удовлетворения.
22 vmv
 
07.11.11
09:51
(21) я тупой одинесник, предпочитаю все воровать, каюс
23 Balabass
 
07.11.11
09:56
(21)Я щас сам свояю. Щас потестю - и выкладу :D
24 vmv
 
07.11.11
09:59
ТекстЗапроса = "ВЫБРАТЬ РАЗЛИЧНЫЕ
   |   ТаблицаОбъекта.Код КАК Код,
     |    ТаблицаОбъекта.Ссылка КАК Ссылка,
   |   ТаблицаОбъекта.Родитель КАК РодительСсылок
   |ИЗ
   |  " + ПолноеИмяТаблицы + " КАК ТаблицаОбъекта";    
   ТекстЗапроса = ТекстЗапроса + "
   |ГДЕ
   |    ТаблицаОбъекта.Ссылка В (&Ссылка)
   |ИТОГИ ПО
   |    Ссылка ТОЛЬКО ИЕРАРХИЯ";
   
   Запрос = Новый Запрос;

   
   Запрос.УстановитьПараметр("Ссылка", Ссылка); // Вложенная ссылка, массив или список оных

это классика
25 Balabass
 
07.11.11
10:00
ВремПоздразделение = справочники.ПодразделенияОрганизаций.НайтиПоКоду(сокрлп(строка.дт1));
   Если ВремПоздразделение.Уровень()>1 тогда
       ПолныйКод = ВремПоздразделение.ПолныйКод();
       Массив = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(строка.дт1, "/");
       строка.дт1 = справочники.ПодразделенияОрганизаций.НайтиПоКоду(массив[1]);  
   иначе
       строка.дт1 = ВремПоздразделение.Код;
   конецесли;
26 Wobland
 
07.11.11
10:00
(25) а говорил, ссылка не нужна
27 Balabass
 
07.11.11
10:01
(26) Где?
28 Wobland
 
07.11.11
10:02
(27) в (4)
29 Balabass
 
07.11.11
10:02
(28) строка.дт1 = справочники.ПодразделенияОрганизаций.НайтиПоКоду(массив[1]);  Это?
30 Balabass
 
07.11.11
10:05
Ой..все *уйня. давай сначало
31 Axel2009
 
07.11.11
10:08
в одной строке получаешь ссылку, в другой код. ты уж определись
32 Balabass
 
07.11.11
10:08
Вот так вроде работает:

   Если ВремПоздразделение.Уровень()>1 тогда
       ПолныйКод = ВремПоздразделение.ПолныйКод();
       Массив = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(ПолныйКод, "/");
       ВремПоздразделение = справочники.ПодразделенияОрганизаций.НайтиПоКоду(массив[1]);  
       строка.дт1 = ВремПоздразделение.Код;
   иначе
       строка.дт1 = ВремПоздразделение.Код;
   конецесли;
33 Escander
 
07.11.11
10:09
(9)а на практике в порядочном вузе показывают что любую рекурсию можно свести к циклу и что писать/читать из массива это быстрее чем при вызове самого себя запоминать всё в стек/восстанавливать всё из стека.

(0)Почему-бы не вызывать цикл пока не ПустотоеЗначение от Ссылка.Родитель? и внутри считать уровни... как стало пустым - значит самый верхний уровень. И при переходе через некоторое пороговое значение запоминать родителя в специальную переменную?
34 Balabass
 
07.11.11
10:10
Ура. Все работает. Всем спасибо!
35 Wobland
 
07.11.11
10:10
(32) когда оно тебе в иначе придёт, что будет во ВремПодразделении?
36 Balabass
 
07.11.11
10:11
ВремПоздразделение = справочники.ПодразделенияОрганизаций.НайтиПоКоду(сокрлп(строка.дт1));
+
(32)
37 Escander
 
07.11.11
10:11
(32) как уже писали когда бух тётя Маша в код забъёт символ "/" - внезаптно перестанети работать
38 Balabass
 
07.11.11
10:13
(37)Коды числовые. Универсальность не требэ.
Ну можно и циклом - тут однозначного пути решения нет.
39 Balabass
 
07.11.11
10:14
(38)+В приличных вузах не учился. Не моя тому вина.
40 Megas
 
07.11.11
10:16
Я за (24) .... правда не читал что там, но идея в целом верная. Запросом выбрать иерархию и обойти 2 верхних уровня.
41 Axel2009
 
07.11.11
10:19
зачем это
ВремПоздразделение = справочники.ПодразделенияОрганизаций.НайтиПоКоду(массив[1]);  
       строка.дт1 = ВремПоздразделение.Код;
когда можно
Строка.дт1 = Массив[1];
42 Balabass
 
07.11.11
10:25
(41)Нужен код, а не ссылка.
43 Balabass
 
07.11.11
10:26
*facepalm*
44 Balabass
 
07.11.11
10:35
ну все. взлетело. Всем спасибо еще раз.
Глупец, лишенный способности посмеяться над собой вместе с другими, не сможет долго выносить программирование. Фредерик Брукс-младший