Имя: Пароль:
1C
1С v8
v8: Как к дате прибавить n дней исключая праздники?
0 budnik
 
27.11.13
14:04
Поскажите как лучше
к начальной дате прибавить n дней исключая праздники.
ВЫБРАТЬ
    РегламентированныйПроизводственныйКалендарь.ДатаКалендаря,
    РегламентированныйПроизводственныйКалендарь.Год,
    РегламентированныйПроизводственныйКалендарь.Пятидневка,
    РегламентированныйПроизводственныйКалендарь.Шестидневка,
    РегламентированныйПроизводственныйКалендарь.КалендарныеДни,
    РегламентированныйПроизводственныйКалендарь.ВидДня
ИЗ
    РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
    НЕ РегламентированныйПроизводственныйКалендарь.ВидДня = &ВидДня
1 skunk
 
27.11.13
14:06
тебе именно как прибавить

дтНужнаяДата = дтНачальная + чисКоличествоДней * чисКоличествоСекундВДне
2 budnik
 
27.11.13
14:10
Праздники надо исключить
3 skunk
 
27.11.13
14:12
исключай ...
4 1Сергей
 
27.11.13
14:13
дтНужнаяДата = дтНачальная + (чисКоличествоДней - чисКоличествоПраздников) * чисКоличествоСекундВДне
5 skunk
 
27.11.13
14:13
точнее наоборот ... если я правильно понимаю ...

смотришь какие праздники и выходные попадают в твой период и делаешь оффсет
6 skunk
 
27.11.13
14:14
(4)думаю ему надо на оборот

дтНужнаяДата = дтНачальная + (чисКоличествоДней + чисКоличествоПраздников) * чисКоличествоСекундВДне
7 Fragster
 
модератор
27.11.13
14:14
// добавляет к дате количество рабочих дней по пятидневке/шестидневке/семидневке
Функция ДобавитьДниКДатеСУчетомВыходных(Дата, КоличествоДней, РабочихДней=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 Тогда
        ЭлементОтбора = Построитель.Отбор.Добавить("КалендарныеДни");
    Иначе
        ВызватьИсключение "Неверное количество рабочих дней";
    КонецЕсли;
    ЭлементОтбора.Установить(Цел(КоличествоДней), Истина);
    Построитель.Выполнить();
    Если Построитель.Результат.Пустой() Тогда
        ВызватьИсключение "Не могу определить дату с учетом регламентированного календаря!";
    Иначе
        Выборка = Построитель.Результат.Выбрать();
        Выборка.Следующий();
        Возврат Выборка.ДатаКалендаря;
    КонецЕсли;
КонецФункции
8 Feunoir
 
27.11.13
14:16
ЗаполнениеДокументов.ОпределитьДату(ДатаНач, ЧислоДней)

// Функция возвращает дату отстоящую на заданное количество рабочих дней от начальной в соответствии с
//регламентированным производственным календарем
//
//Параметры:
// ДатаНач      - начальная дата
// ЧислоДней    - количество рабочих дней, на которое искомая дата должна отстоять от начальной
//
9 budnik
 
27.11.13
14:48
Спасибо.