Имя: Пароль:
1C
1С v8
Перенос даты с выходного на рабочую
,
0 anikev
 
21.05.19
15:46
Здравствуйте! Написал небольшой кусок кода, сразу оговорюсь что готов к критике, так как не совсем опытен в программировании. Этот код должен возвращать первый рабочий день, при условии если выпадает на праздничный/выходной. Проблема в том, что функция отрабатывает, все условия, находит рабочую дату, но после строки "возврат Дата " пехеходит в конец функции и опять возвращается на ВычислитьРабочийДень(Дата + (24*60*60)) и делает все в обратном порядке. Подскажите пожалуйста, как будет правильно?

Функция ВычислитьРабочийДень(Дата) Экспорт
    
    Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
|         РегламентированныйПроизводственныйКалендарь.ДатаКалендаря,
|         РегламентированныйПроизводственныйКалендарь.Год,
|         РегламентированныйПроизводственныйКалендарь.Пятидневка,
|         РегламентированныйПроизводственныйКалендарь.Шестидневка,
|         РегламентированныйПроизводственныйКалендарь.КалендарныеДни,
|         РегламентированныйПроизводственныйКалендарь.ВидДня
|     ИЗ
|         РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
|     ГДЕ
|         РегламентированныйПроизводственныйКалендарь.ДатаКалендаря = &ДатаКалендаря";
Запрос.УстановитьПараметр("ДатаКалендаря",    Дата);     //Дата
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
ВидДня = РезультатЗапроса[0].ВидДня ;
//Для Каждого эл Из РезультатЗапроса Цикл
//      ВидДня = Эл.ВидДня
//  КонецЦикла;
Если  ВидДня <> Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий Тогда
    Сообщить("Дата " + Дата + " Выпадает на выходной/праздничный день! Ищем следующий рабочий");
    ВычислитьРабочийДень(Дата + (24*60*60))
  Иначе
      Возврат Дата;
      КонецЕсли;;
Возврат Дата;        
КонецФункции;
1 kda26
 
21.05.19
15:48
рекурсия?
2 anikev
 
21.05.19
15:49
(1) Совершенно верно
3 sqr4
 
21.05.19
15:49
в топку, делай все в запросе
4 bootini
 
21.05.19
15:50
Чтобы понять рекурсию, сперва нужно понять рекурсию. ))
5 sqr4
 
21.05.19
15:50
выбираешь все даты, которые больше или равны твоей с видом рабочий и затем группировка по минимуму
6 anikev
 
21.05.19
15:50
Я ее понимаю, и она отрабатывает ну почти как надо)
7 bootini
 
21.05.19
15:53
В запросе условие ДатаКалендаря <= &Дата и МАКСИМУМ по полю ДатаКалендаря и ну и ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий
8 anikev
 
21.05.19
15:54
Получилось вот так

ВЫБРАТЬ
    Минимум (РегламентированныйПроизводственныйКалендарь.ДатаКалендаря)
ИЗ
    РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
    РегламентированныйПроизводственныйКалендарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
        И РегламентированныйПроизводственныйКалендарь.ДатаКалендаря > &ДатаКалендаря
9 Temai
 
21.05.19
15:55
Может эта функция натолкнёт на мысль:

Функция ЭтоРабочийДень(ПроверяемаяДата = Неопределено) Экспорт
    Если ПроверяемаяДата = Неопределено или ПроверяемаяДата = Дата(1,1,1) Тогда
        ПроверяемаяДата = ТекущаяДата();
    КонецЕсли;
    НаборЗаписей = РегистрыСведений.РегламентированныйПроизводственныйКалендарь.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.ДатаКалендаря.Установить(ПроверяемаяДата);
    НаборЗаписей.Прочитать();
    Если НаборЗаписей.Количество() > 0 Тогда
        ВидДня = НаборЗаписей[0].ВидДня;
        Если ВидДня  = Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий или ВидДня  = Перечисления.ВидыДнейПроизводственногоКалендаря.Предпраздничный Тогда
            Возврат Истина;
        Иначе
            Возврат Ложь;
        КонецЕсли;
    Иначе
        Возврат Истина;
    КонецЕсли;
    
КонецФункции
10 bootini
 
21.05.19
15:56
(8) ну да я наоборот написал, найти ближайший прошедший рабочий день, а у тебя надо было последующий
11 trooba
 
21.05.19
15:58
ВЫБРАТЬ
    
    РегламентированныйПроизводственныйКалендарь.Дата КАК Дата
    
ПОМЕСТИТЬ Вт_Дат
ИЗ
    РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
    РегламентированныйПроизводственныйКалендарь.Дата >= &Дата
    И РегламентированныйПроизводственныйКалендарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    МИНИМУМ(Вт_Дат.Дата) КАК Дата
ИЗ
    Вт_Дат КАК Вт_Дат
12 anikev
 
21.05.19
16:07
(9) Изящно, но функция берет только текущую дату, сюда рекурсию так же я могу дописать?
13 Йохохо
 
21.05.19
16:09
(12) лучше утащи к себе рекурсивно предпраздичный
14 anikev
 
21.05.19
16:11
(13) немного перестал понимать)
15 Temai
 
21.05.19
16:13
(12) Конечно, вызывай её из другой процедуры
16 Йохохо
 
21.05.19
16:15
(14) ну Перечисления.ВидыДнейПроизводственногоКалендаря.Предпраздничный равно Рабочий, но не рекурсивно и не наоборот
17 Йохохо
 
21.05.19
16:18
во
Запрос = Новый Запрос;
Запрос.Текст = Запрос = Новый Запрос;
18 anikev
 
21.05.19
16:23
(17) высший пилотаж какой-то