Имя: Пароль:
1C
1С v8
Получить будущую дату запросом (из задачи на Спец по БП)
0 Allexe
 
03.09.13
18:47
Вопрос по задаче 3 на специалиста по БП из нового сборника
Суть задачи:
Есть дата начала переработки, срок исполнения в РАБОЧИХ днях и производственный календарь с измерением дата и ресурсом ВидДня где рабочие дни это перечисления Рабочий, Предпраздничный.
Необходимо получить:
Дата окончания переработки.

Возможно ли получить эту дату запросом?

Пока вижу два варианта:
1. Тупо в лоб перебирать циклом даты из производственного календаря с ДатыНачала набирая рабочие дни пока их количество не будет равным сроку переработки
2. Принять упрощенние что допустим не может быть 100 выходных подряд. Тогда можно запросом набрать дней в периоде НачДата, НачДата+СрокДней+100Дней и вычислить день окончания.
Такие варианты пройдут на экзамене? Или все таки можно получить красиво запросом?
1 PR
 
03.09.13
18:48
(0) А почему бы не выбирать только рабочие дни, нужное количество?
2 Allexe
 
03.09.13
18:49
(1) Перебором, т.е. циклом? Пока не наберется нужное количество (т.е. срок исполнения в Рабочих днях)?
3 yukon
 
03.09.13
19:04
(0) БСП:

// Функция возвращает массив дат, которые отличается указанной даты на количество дней, входящих в указанный график
КалендарныеГрафики.ПолучитьМассивДатПоКалендарю(...)
4 Allexe
 
03.09.13
19:06
(3) Всем спасибо разобрался можно получить через ВЫБРАТЬ ПЕРВЫЕ СРОК и далее поставить условие в запросе только рабочие дни
5 Noob_Of_1C
 
03.09.13
19:11
(4) черт, не успел дописать
6 Fragster
 
модератор
03.09.13
19:13
Функция ДобавитьДниКДатеСУчетомВыходных(НачальнаяДата, КоличествоДней, РабочихДней=5) Экспорт
    Построитель = Новый ПостроительЗапроса;
    Если КоличествоДней > 0 Тогда
        Построитель.Текст =
        "ВЫБРАТЬ
        |    РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК ДатаКалендаря,
        |    РегламентированныйПроизводственныйКалендарь.Пятидневка,
        |    РегламентированныйПроизводственныйКалендарь.Шестидневка,
        |    РегламентированныйПроизводственныйКалендарь.КалендарныеДни
        |ПОМЕСТИТЬ КусокКалендаря
        |ИЗ
        |    РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
        |ГДЕ
        |    РегламентированныйПроизводственныйКалендарь.ДатаКалендаря МЕЖДУ &Дата1 И &Дата2
        |
        |ИНДЕКСИРОВАТЬ ПО
        |    ДатаКалендаря
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ ПЕРВЫЕ 1
        |    КусокКалендаря.ДатаКалендаря КАК ДатаКалендаря
        |ИЗ
        |    КусокКалендаря КАК КусокКалендаря
        |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ КусокКалендаря КАК Накопление
        |        ПО КусокКалендаря.ДатаКалендаря >= Накопление.ДатаКалендаря
        |{ГДЕ
        |    (СУММА(Накопление.Пятидневка) - 1) КАК Пятидневка,
        |    (СУММА(Накопление.Шестидневка) - 1) КАК Шестидневка,
        |    (СУММА(Накопление.КалендарныеДни) - 1) КАК КалендарныеДни}
        |
        |СГРУППИРОВАТЬ ПО
        |    КусокКалендаря.ДатаКалендаря
        |
        |УПОРЯДОЧИТЬ ПО
        |    ДатаКалендаря";
    ИначеЕсли КоличествоДней < 0 Тогда
        Построитель.Текст =
        "ВЫБРАТЬ
        |    РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК ДатаКалендаря,
        |    РегламентированныйПроизводственныйКалендарь.Пятидневка,
        |    РегламентированныйПроизводственныйКалендарь.Шестидневка,
        |    РегламентированныйПроизводственныйКалендарь.КалендарныеДни
        |ПОМЕСТИТЬ КусокКалендаря
        |ИЗ
        |    РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
        |ГДЕ
        |    РегламентированныйПроизводственныйКалендарь.ДатаКалендаря МЕЖДУ &Дата2 И &Дата1
        |
        |ИНДЕКСИРОВАТЬ ПО
        |    ДатаКалендаря
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ ПЕРВЫЕ 1
        |    КусокКалендаря.ДатаКалендаря КАК ДатаКалендаря
        |ИЗ
        |    КусокКалендаря КАК КусокКалендаря
        |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ КусокКалендаря КАК Накопление
        |        ПО КусокКалендаря.ДатаКалендаря <= Накопление.ДатаКалендаря
        |{ГДЕ
        |    (-СУММА(Накопление.Пятидневка) + 1) КАК Пятидневка,
        |    (-СУММА(Накопление.Шестидневка) + 1) КАК Шестидневка,
        |    (-СУММА(Накопление.КалендарныеДни) + 1) КАК КалендарныеДни}
        |
        |СГРУППИРОВАТЬ ПО
        |    КусокКалендаря.ДатаКалендаря
        |
        |УПОРЯДОЧИТЬ ПО
        |    ДатаКалендаря УБЫВ";
    ИначеЕсли КоличествоДней = 0 Тогда
        Возврат НачальнаяДата;
    Иначе
        ВызватьИсключение "Неверное количество добавляемых дней";
    КонецЕсли;
    Построитель.Параметры.Вставить("Дата1", НачальнаяДата);
    КолНедель = Цел(КоличествоДней / РабочихДней) + ?(КоличествоДней > 0, 1, -1);
    КолЛет =    Цел(КолНедель / 52)               + ?(КоличествоДней > 0, 1, -1);
    Добавляем = КолНедель * 7 + КолЛет * 20; // с запасом, например для майских праздников или новогодних каникул, допустим, у нас праздничных дней 20 в году

    Построитель.Параметры.Вставить("Дата2", НачальнаяДата + 86400*Добавляем);
    
    Если РабочихДней = 5 Тогда
        ЭлементОтбора = Построитель.Отбор.Добавить("Пятидневка");
    ИначеЕсли РабочихДней = 6 Тогда
        ЭлементОтбора = Построитель.Отбор.Добавить("Шестидневка");
    ИначеЕсли РабочихДней = 7 Тогда
        ЭлементОтбора = Построитель.Отбор.Добавить("КалендарныеДни");
    Иначе
        ВызватьИсключение "Неверное количество рабочих дней";
    КонецЕсли;
    ЭлементОтбора.Установить(Цел(КоличествоДней), Истина);
    Построитель.Выполнить();
    Если Построитель.Результат.Пустой() Тогда
        ВызватьИсключение "Не могу определить дату с учетом регламентированного календаря!";
    Иначе
        Выборка = Построитель.Результат.Выбрать();
        Выборка.Следующий();
        Возврат Выборка.ДатаКалендаря;
    КонецЕсли;
КонецФункции