```1c
    Функция ПолучитьПредыдущийРабочийДень(ПроверяемаяДата)
    ПроверяемаяДата = ПроверяемаяДата - 86400;
    Нашли = ГрафикиРаботы.ЭтоРабочийДень(ПроверяемаяДата,справочники.графикиработы.найтипонаименованию("Основной график"));
    Если Нашли Тогда
    возврат ПроверяемаяДата;
    Иначе
    ПолучитьПредыдущийРабочийДень(ПроверяемаяДата);
    КонецЕсли;
    КонецФункции
```

Функция почему-то возвращает временами неопределено. Если смотреть в отладчике то в момент когда находится нужная дата заходит в возврат, идет до конца функции и возвращается в иначе. При этом "Нашли" становится равно Ложь
---
как-то так:

```1c
    Функция ПолучитьПредыдущийРабочийДень(ПроверяемаяДата)
    ПроверяемаяДата = ПроверяемаяДата - 86400;
    Нашли = ГрафикиРаботы.ЭтоРабочийДень(ПроверяемаяДата,справочники.графикиработы.найтипонаименованию("Основной график"));
    Если Не Нашли Тогда
    ПроверяемаяДата = ПолучитьПредыдущийРабочийДень(ПроверяемаяДата);
    КонецЕсли;
    возврат ПроверяемаяДата;
    КонецФункции
```
---
как-то так:

```1c
    Функция ПолучитьПредыдущийРабочийДень(ПроверяемаяДата)
    ПроверяемаяДата = ПроверяемаяДата - 86400;
    Нашли = ГрафикиРаботы.ЭтоРабочийДень(ПроверяемаяДата,справочники.графикиработы.найтипонаименованию("Основной график"));
    Если Не Нашли Тогда
    ПроверяемаяДата = ПолучитьПредыдущийРабочийДень(ПроверяемаяДата);
    КонецЕсли;
    возврат ПроверяемаяДата;
    КонецФункции
```
---
Если ПроверяемаяДата равна 01.06.2019,02.06.2019, 01.05.2019 то все хорошо, возвращает то что нужно. А вот если 02.05.2019 или 03.05.2019 то пусто
---
попробуй заменить функцию процедурой
---
переполнение стека
(4) работает. Спасибо! Не понятно правда почему мой вариант "зацикливался"
---
была похожая ситуация ))
---
потому, что при Иначе ничего не возвращается. А если функция ничего не возвращает, то возвращается Неопределено.
А рекурсия в данном случае при попадании в Иначе вызывает новую функцию. И даже если она возвращает Дату, то в исходной функции (первый уровень рекурсии) эта дата не используется и продолжается выполнение секции Иначе. Т.е. в итоге функция возвращает Неопределено.
---
понятно
(9) смешно б...
---
Совет избавиться от рекурсии - вполне дельный. Сабжевый код - пример плохого применения рекурсии. Она здесь не нужна. Она здесь ничего не упрощает, только добавляет накладных расходов.
---
т.е. оптимальнее будет цикл и дерганье справочника на предмет проверки рабочий или праздничный/выходной?
подскажите хороший пример для такого случая
---
Конечно цикл будет оптимальнее. Вы же и переложили на рекурсию самый примитивный цикл - никакого состояния там хранить не требуется.
То, что вы в каждой итерации дергаете справочник - это на вашей совести. С чего вы вдруг решили, что в рекурсивном исполнении он вдруг "дергаться" перестанет?
---
ну по крайней мере он здесь реже дергается. Разве нет?
---
С чего это? Наоборот. Поиск ссылки на основной график естественным образом делается перед циклом один раз. А в текущей рекурсивной реализации это сейчас у вас происходит в каждой итерации.
Ну, тут вообще много проблем вижу. Не обрабатываются краевые случаи (не задана максимальная глубина поиска и что делать при ее достижении). Да и вообще это запросом эффективнее реализовывать. Ведь насколько я понимаю, функция ЭтоРабочийДень() обращается к БД и в итоге получаются многострадальные "запросы в цикле", хоть с ног до головы рекурсией обмазывайся :)
---
Берем как предложено в (9) цикл от 1 до 365. , столько же раз и обратимся к справочнику. Правильно?
В моем коде передаем дату, обращаемся к справочнику. Если день не рабочий- повторяем. Максимальное число обращений к справочнику будет в случае, когда проверяемая дата будет входить в новогодние праздники. Где я не прав?
---
Вы чересчур буквально восприняли совет. Ессно, 365 предлагалось в качестве максимальной глубины поиска. Предполагалось что-то типа такого:

```1c
    Функция ПолучитьПредыдущийРабочийДень(ПроверяемаяДата, Знач График = Неопределено, ГлубинаПоиска = 30)

    Если График = Неопределено Тогда
    График = ПредопределенноеЗначение("Справочник.ГрафикиРаботы.Основной");
    КонецЕсли;

    РабочийДень = Неопределено;
    Для НомерДня = 1 По ГлубинаПоиска Цикл
    ТекущийДень = ПроверяемаяДата - НомерДня * 86400;
    Если ГрафикиРаботы.ЭтоРабочийДень(ТекущийДень, График) Тогда
    РабочийДень = ТекущийДень;
    Прервать;
    КонецЕсли;
    КонецЦикла;

    Возврат РабочийДень;

    КонецФункции
```

Но лучше запросом.
---
Если так то да согласен
---
(14)
Отличия цикла и рекурсии будут только в том, что при реализации "в цикле" код будет более читаемо восприниматься.
Количество "дерганий" никак не изменится.
---
```1c
    Процедура ПолучитьПредыдущийРабочийДень(ПроверяемаяДата)
    ПрДата = ПроверяемаяДата - 86400;
    Нашли = ГрафикиРаботы.ЭтоРабочийДень(ПрДата ,справочники.графикиработы.найтипонаименованию("Основной график"));
    Если Нашли Тогда
    ПроверяемаяДата = ПрДата ;
    Иначе
    ПолучитьПредыдущийРабочийДень(ПрДата );
    КонецЕсли;
    КонецФункции
```
---
Напиши код процедуры ЭтоРабочийДень(). Есть вероятность, что в процедуру надо передавать НачалоДня(ПроверяемаяДата). Даи вообще рекурсию желательно заменить на цикл от 1 до 365.
---
```1c
    График = справочники.графикиработы.найтипонаименованию("Основной график");

    Для Инд = 1 По 365 Цикл

    ПроверяемаяДата = ПроверяемаяДата - 86400;

    Если ГрафикиРаботы.ЭтоРабочийДень(ПроверяемаяДата,График ) Тогда
    Прервать;
    КонецЕсли;

    КонецЦикла;
```