![]() |
|
Количество рабочих дней между двумя датами | ☑ | ||
---|---|---|---|---|
0
swallow05
15.08.11
✎
22:59
|
Доброй ночи всем. Возникла необходимость отсчитать от определенной даты назад 5 рабочих дней, т.е. с учетом праздников и выходных. Добавила в конфигурацию производственный календарь (конфа бухгалтерия 1.6), но чую им не получится это сделать. Никто не подскажет, каким образом можно реализовать такой подсчет? Т.е. если у нас 11 января, то 5 рабочих дней будет 26 декабря. Спасибо за ответы :).
|
|||
1
vde69
15.08.11
✎
23:08
|
делал через производственный календарь, делается не сложно но работает медлено.
потом оптимизировал, сделал кеш таблицу и ее использовал, экономия примерно 4-5 секунд на запросе |
|||
2
Мимохожий Однако
15.08.11
✎
23:10
|
Поищи в общих модулях. Наверняка уже есть готовое в конфигурации.
|
|||
3
swallow05
15.08.11
✎
23:12
|
Я сейчас просто выборку делаю из производственного календаря первый 5 дней, по условию рабочих, которые меньше данной даты, вроде получилось, всем спасибо. Вопрос закрыт :)
|
|||
4
CepeLLlka
16.08.11
✎
00:08
|
"Добавила в конфигурацию производственный календарь"
Пол: Мужской о_О |
|||
5
swallow05
16.08.11
✎
01:21
|
Изменила профиль))) при регистрации видимо немного промахнулась)))
|
|||
6
Steel_Wheel
16.08.11
✎
01:59
|
ник просто ппц
|
|||
7
Sammo
16.08.11
✎
04:52
|
Вообще-то задача в теме (рабочих дней между датами) и в сообщении (нужно отнять 5 дней от даты) несколько разные.
Делаются разными запросами по производственному календарю |
|||
8
skunk
16.08.11
✎
04:57
|
(7)и в чем разница?
|
|||
9
kosts
16.08.11
✎
06:06
|
(1) Это что за запрос такой по которому только экономия 4-5 секунд...
(3) Нужно учесть предпразднечные дни, они ведь тоже рабочие. По крайней мере в ЗУПе есть предпразднечные. |
|||
10
Мимохожий Однако
16.08.11
✎
06:56
|
УТ11. Общий модуль.Календарные графики.
// Функция определяет количество дней, входящих в календарь, для указанного периода // // Параметры // Календарь - календарь, который необходимо использовать, тип СправочникСсылка.Календари // ДатаНачала - дата начала периода // ДатаОкончания - дата окончания периода // // Возвращаемое значение // Массив - массив дат, увеличенных на количество дней, входящих в график // Функция ПолучитьРазностьДатПоКалендарю(Знач Календарь, Знач ДатаНачала, Знач ДатаОкончания) Экспорт ДатаНачала = НачалоДня(ДатаНачала); ДатаОкончания = НачалоДня(ДатаОкончания); Если ДатаНачала = ДатаОкончания Тогда Возврат 0; КонецЕсли; РазныеГода = Год(ДатаНачала) <> Год(ДатаОкончания); Запрос = Новый Запрос; МассивДатНачала = Новый Массив; МассивДатНачала.Добавить(ДатаНачала); Если РазныеГода Тогда МассивДатНачала.Добавить(НачалоДня(КонецГода(ДатаНачала))); КонецЕсли; Запрос.УстановитьПараметр("Календарь", Календарь); Запрос.УстановитьПараметр("МассивДатНачала", МассивДатНачала); Запрос.УстановитьПараметр("ГодДатыНачала", Год(ДатаНачала)); Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания); Запрос.УстановитьПараметр("ГодДатыОкончания", Год(ДатаОкончания)); Запрос.Текст = "ВЫБРАТЬ | КалендарныеГрафики.КоличествоДнейВГрафикеСНачалаГода КАК КоличествоДней, | КалендарныеГрафики.ДатаГрафика КАК ДатаГрафика |ИЗ | РегистрСведений.КалендарныеГрафики КАК КалендарныеГрафики |ГДЕ | КалендарныеГрафики.Календарь = &Календарь | И (КалендарныеГрафики.Год = &ГодДатыНачала | И КалендарныеГрафики.ДатаГрафика В (&МассивДатНачала) | ИЛИ КалендарныеГрафики.Год = &ГодДатыОкончания | И КалендарныеГрафики.ДатаГрафика = &ДатаОкончания) | |УПОРЯДОЧИТЬ ПО | ДатаГрафика"; ТаблицаДней = Запрос.Выполнить().Выгрузить(); Если ТаблицаДней.Количество() < ?(РазныеГода, 3, 2) Тогда СообщениеОбОшибке = НСтр("ru = 'Не заполнен календарь ''%1'' за период %2!'"); ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( СообщениеОбОшибке, Календарь, ПредставлениеПериода(ДатаНачала, КонецДня(ДатаОкончания))); КонецЕсли; КоличествоДнейДатыНачала = ТаблицаДней[0].КоличествоДней; КоличествоДнейДатыОкончания = ТаблицаДней[?(РазныеГода, 2, 1)].КоличествоДней + ?(РазныеГода, ТаблицаДней[1].КоличествоДней, 0); Возврат КоличествоДнейДатыОкончания - КоличествоДнейДатыНачала; КонецФункции |
|||
11
vde69
16.08.11
✎
08:37
|
вот это приведение долго работает...
ЗапросКаледарь = Новый Запрос( "ВЫБРАТЬ | ПроизводственныйКалендарь.ДатаКалендаря КАК ДатаКалендаря, | МИНИМУМ(ПроизводственныйКалендарь.ДатаКалендаря) КАК ДатаНачалаКалендаря, | СУММА(ВЫБОР | КОГДА ПроизводственныйКалендарь.Пятидневка = 1 | ТОГДА КопияПроизводственныйКалендарь.Пятидневка | ИНАЧЕ NULL | КОНЕЦ) КАК ИндексПятидневка, | СУММА(ВЫБОР | КОГДА ПроизводственныйКалендарь.Шестидневка = 1 | ТОГДА КопияПроизводственныйКалендарь.Шестидневка | ИНАЧЕ NULL | КОНЕЦ) КАК ИндексШестидневка, | СУММА(ВЫБОР | КОГДА ПроизводственныйКалендарь.КалендарныеДни = 1 | ТОГДА КопияПроизводственныйКалендарь.КалендарныеДни | ИНАЧЕ NULL | КОНЕЦ) КАК ИндексКалендарныеДни, | СУММА(1) КАК ИндексВсеДни |ИЗ | РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК ПроизводственныйКалендарь | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК КопияПроизводственныйКалендарь | ПО ПроизводственныйКалендарь.ДатаКалендаря >= КопияПроизводственныйКалендарь.ДатаКалендаря | |СГРУППИРОВАТЬ ПО | ПроизводственныйКалендарь.ДатаКалендаря | |УПОРЯДОЧИТЬ ПО | ДатаКалендаря"); Кеш = ЗапросКаледарь.Выполнить().Выгрузить(); КешКалендаря = Новый Соответствие; КешКалендаря.Вставить("Календарь", Кеш); ПараметрыСеанса.КешКалендаря = Новый ХранилищеЗначения (КешКалендаря); |
|||
12
vde69
16.08.11
✎
08:40
|
(11) кстати разность дат в SQL работает на порядок медленее чем разность чисел, по этому я и привожу весь календарь к числу дней от самого первого дня, ну а потом просто получаю ю два числа и результатом является простая разница целых чисел
|
|||
13
Fragster
гуру
16.08.11
✎
08:48
|
(11) о_О занафига само с собой соединять?
ВЫБРАТЬ СУММА(ПроизводственныйКалендарь.Пятидневка) КАК Дней ИЗ РегистрСведений.РегламентированныйПроизводственныйКалендарь ГДЕ ПроизводственныйКалендарь.ДатаКалендаря МЕЖДУ &Дата1 И &Дата2 |
|||
14
vde69
16.08.11
✎
08:56
|
(13) по тому как я получаю таблицу для каждой даты, в том числе и для выходных.
для единичного запроса (13) годится, для запроса где нужно посчитать 100 000 периодов годится (11) |
|||
15
Fragster
гуру
16.08.11
✎
08:59
|
(14) считай разность дат в секундах, потом дели на 86400
|
|||
16
Axel2009
16.08.11
✎
09:21
|
(14) 100 000 периодов - 273 года.
|
|||
17
Axel2009
16.08.11
✎
09:23
|
(12) пруфлинк?
|
|||
18
vde69
16.08.11
✎
09:33
|
(16) пример - определение просрочки в супермаркете, по остаткам партий товаров. Или расчет количества банковских дней просрочки по договору (от момента платежа)
(17) замерял |
|||
19
Axel2009
16.08.11
✎
09:34
|
(18) где?
|
|||
20
vde69
16.08.11
✎
09:35
|
(19) в SQL
|
|||
21
dmpl
16.08.11
✎
09:40
|
(14) Когда будет 100 тыс. периодов - сервак просто упадет по нехватке памяти. Левое соединение с условием, отличным от = завалит.
(16) Для того, чтобы завалить сервер хватит и 30-40 тыс. записей. |
|||
22
Axel2009
16.08.11
✎
09:40
|
(18) да я знаю где это применяется. определяю среднюю просрочку (суммарная просрочка на каждый день месяца, и средняя из этого) по каждому клиенту за весь месяц по всем просроченным долгам на 5 рабочих дней. весь запрос 3 секунды
|
|||
23
Axel2009
16.08.11
✎
09:42
|
(20) как проверялось? в цикле или в запросе?
|
|||
24
Axel2009
16.08.11
✎
10:04
|
set nocount on
declare t table(i int, d datetime) declare i int, @d datetime, @d2 datetime, i2 int set i = 0 while i < 10000 begin set i = i + 1 insert into t values(i, dateadd(dd, i, '19500101')) end set i = 0 set @d = getdate() while i < 10000 begin set i = i + 1 select @d2 = datediff(dd, d, getdate()) from t end print 'разница по дате ' + str(datediff(ss, @d, getdate())) set i = 0 set @d = getdate() while i < 10000 begin set i = i + 1 select i2 = 11000 - i from t end print 'разница по числу ' + str(datediff(ss, @d, getdate())) разница по дате 15 разница по числу 14 где порядки? |
|||
25
ptiz
16.08.11
✎
10:27
|
(24) Это в рабочих днях?
|
|||
26
Axel2009
16.08.11
✎
10:28
|
(25) это разность дат, которая "работает на порядок медленнее"
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |