8.х Вопрос по коду в рекурентной функции

Тема в разделе "Конфигурирование на платформе "1С:Предприятие 8"", создана пользователем JVN, 28 сен 2010.

  1. TopicStarter Overlay
    JVN
    Offline

    JVN Опытный в 1С

    Регистрация:
    25 июн 2009
    Сообщения:
    95
    Симпатии:
    0
    Баллы:
    26
    Уважаемые форумчане, надеюсь у меня совсем плевый вопрос:
    вызываю функцию:
    Код:
    РуководительИДолжностьФилиала = РуководительДолжностьФилиала(ВыборкаДляШапки.Подразделение);
    
    
    текст функции:
    Код:
    Функция РуководительДолжностьФилиала(Подразделение)
    РуководительИДолжностьФилиала = "";
    Запрос = Новый Запрос();
    Запрос.УстановитьПараметр("СтруктурнаяЕдиница",  Подразделение);
    Запрос.Текст = "ВЫБРАТЬ
    |	ОтветственныеЛицаОрганизацийСрезПоследних.ФизическоеЛицо,
    |	ОтветственныеЛицаОрганизацийСрезПоследних.Должность
    |ИЗ
    |	РегистрСведений.ОтветственныеЛицаОрганизаций.СрезПоследних КАК ОтветственныеЛицаОрганизацийСрезПоследних
    |ГДЕ
    |	ОтветственныеЛицаОрганизацийСрезПоследних.СтруктурнаяЕдиница = &СтруктурнаяЕдиница";
    РезультатЗапроса = Запрос.Выполнить().Выбрать();
    Если РезультатЗапроса.Следующий() Тогда
    РуководительИДолжностьФилиала = РезультатЗапроса;
    Иначе
    РуководительДолжностьФилиала(Подразделение.Родитель);
    КонецЕсли;
    
    Возврат РуководительИДолжностьФилиала; 
    
    КонецФункции
    
    
    по идее функция ищет руководителей по подразделению, а если не нашла, то по его родителям, но после возврата идет по ветке кода Иначе. Почему так происходит?
  2. Наташа
    Offline

    Наташа Опытный в 1С

    Регистрация:
    14 авг 2010
    Сообщения:
    1.442
    Симпатии:
    2
    Баллы:
    29
    Код:
    Если РезультатЗапроса.Следующий() Тогда
    РуководительИДолжностьФилиала = РезультатЗапроса;
    Иначе
    РуководительИДолжностьФилиала  = РуководительДолжностьФилиала(Подразделение.Родитель);
    КонецЕсли;
    
    
    Попробуйте, например, так.
  3. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Наташа уже сказала. Добавлю: почему вы не ограничиваете уровень рекурсии? (никак не контролируете его, это неправильно) При "отсутствие руководителя в принципе" (он не задан ни для одного из подразделений) вы загоните алгоритм в непрерывный цикл.

    Как-то так что-ли:
    Код:
    Процедура Получить()
    РуководительИДолжностьФилиала = РуководительДолжностьФилиала(ВыборкаДляШапки.Подразделение, 0);
    Если РуководительИДолжностьФилиала <> Неопределено Тогда
    РуководительИДолжностьФилиала.Следующий();
    ...
    ...
    ...
    Иначе
    ...
    ...
    ...
    КонецЕсли;
    
    КонецПроцедуры
    
    
    
    Функция РуководительДолжностьФилиала(Подразделение, знач УровеньРекурсии)
    Запрос = Новый Запрос();
    Запрос.УстановитьПараметр("СтруктурнаяЕдиница",  Подразделение);
    Запрос.Текст = "ВЫБРАТЬ
    |	ОтветственныеЛицаОрганизацийСрезПоследних.ФизическоеЛицо,
    |	ОтветственныеЛицаОрганизацийСрезПоследних.Должность
    |ИЗ
    |	РегистрСведений.ОтветственныеЛицаОрганизаций.СрезПоследних КАК ОтветственныеЛицаОрганизацийСрезПоследних
    |ГДЕ
    |	ОтветственныеЛицаОрганизацийСрезПоследних.СтруктурнаяЕдиница = &СтруктурнаяЕдиница";
    РезультатЗапроса = Запрос.Выполнить();
    Если РезультатЗапроса.Пустой() Тогда
    Если УровеньРекурсии < 5 Тогда
    Возврат (РуководительДолжностьФилиала(Подразделение.Родитель), УровеньРекурсии + 1);
    Иначе 
    Возврат Неопределено;
    КонецЕсли;
    Иначе
    Возврат (РезультатЗапроса.Выбрать());
    КонецЕсли;
    
    КонецФункции
    
    
  4. TopicStarter Overlay
    JVN
    Offline

    JVN Опытный в 1С

    Регистрация:
    25 июн 2009
    Сообщения:
    95
    Симпатии:
    0
    Баллы:
    26
    Спасибо, помогло, бывают иногда и такие затупы )
  5. Itsys
    Offline

    Itsys Опытный в 1С

    Регистрация:
    3 янв 2010
    Сообщения:
    1.394
    Симпатии:
    0
    Баллы:
    26
    А не проще ли сначала выбрать всю иерархию, выгрузить в ТЗ, сделать запрос по этой ТЗ с объединением по регистру ответсвенных лиц... и можно уложиться в одну процедуру и не мучать рекурсию.

    Да, запрос выборки всех родителей элемента:
    Код:
    ВЫБРАТЬ
    Подразделения.Ссылка КАК Ссылка
    ИЗ
    Справочник.ПодразделенияОрганизаций КАК Подразделения
    ГДЕ
    Подразделения.Ссылка = &Ссылка
    ИТОГИ ПО
    Ссылка ТОЛЬКО ИЕРАРХИЯ
    
  6. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Itsys, ну в общем то может и проще. Кроме того тогда конечно не будет запроса в цикле.

    Вот что должен признать: к сожалению во временных таблицах "итоги" нельзя использовать.. :(

    А можно еще и вот так поизвращаться одним запросом:
    Код:
    ВЫБРАТЬ
    ВнутреннийЗапрос.Подразделение,
    ВнутреннийЗапрос.Уровень
    ПОМЕСТИТЬ ИерархияПредприятия
    ИЗ
    (ВЫБРАТЬ
    Подразделения.Ссылка КАК Подразделение,
    1 КАК Уровень
    ИЗ
    Справочник.ПодразделенияОрганизаций КАК Подразделения
    ГДЕ
    Подразделения.Ссылка = &СтруктурнаяЕдиница
    
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
    Подразделения.Родитель,
    2
    ИЗ
    Справочник.ПодразделенияОрганизаций КАК Подразделения
    ГДЕ
    Подразделения.Ссылка = &СтруктурнаяЕдиница
    
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
    Подразделения.Родитель.Родитель,
    3
    ИЗ
    Справочник.ПодразделенияОрганизаций КАК Подразделения
    ГДЕ
    Подразделения.Ссылка = &СтруктурнаяЕдиница
    
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
    Подразделения.Родитель.Родитель.Родитель,
    3
    ИЗ
    Справочник.ПодразделенияОрганизаций КАК Подразделения
    ГДЕ
    Подразделения.Ссылка = &СтруктурнаяЕдиница
    
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
    Подразделения.Родитель.Родитель.Родитель.Родитель,
    4
    ИЗ
    Справочник.ПодразделенияОрганизаций КАК Подразделения
    ГДЕ
    Подразделения.Ссылка = &СтруктурнаяЕдиница
    
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
    Подразделения.Родитель.Родитель.Родитель.Родитель.Родитель,
    5
    ИЗ
    Справочник.ПодразделенияОрганизаций КАК Подразделения
    ГДЕ
    Подразделения.Ссылка = &СтруктурнаяЕдиница) КАК ВнутреннийЗапрос
    ГДЕ
    ВнутреннийЗапрос.Подразделение <> ЗНАЧЕНИЕ(Справочник.ПодразделенияОрганизаций.ПустаяСсылка)
    ;
    
    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ ПЕРВЫЕ 1
    ОтветственныеЛицаОрганизацийСрезПоследних.ФизическоеЛицо,
    ОтветственныеЛицаОрганизацийСрезПоследних.Должность,
    ИерархияПредприятия.Подразделение
    ИЗ
    ИерархияПредприятия КАК ИерархияПредприятия
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ОтветственныеЛицаОрганизаций.СрезПоследних КАК ОтветственныеЛицаОрганизацийСрезПоследних
    ПО ИерархияПредприятия.Подразделение = ОтветственныеЛицаОрганизацийСрезПоследних.СтруктурнаяЕдиница
    ГДЕ
    ((НЕ ОтветственныеЛицаОрганизацийСрезПоследних.ФизическоеЛицо ЕСТЬ NULL )
    ИЛИ (НЕ ОтветственныеЛицаОрганизацийСрезПоследних.Должность ЕСТЬ NULL ))
    
    УПОРЯДОЧИТЬ ПО
    ИерархияПредприятия.Уровень

Поделиться этой страницей