gifts2017

Подсчет банковских дней

Опубликовал Сэр Артур (kite2) в раздел Программирование - Практика программирования

Алгоритм расчета банковских дней от заданной даты, опираясь на производственный календарь.
Внимание! Предпраздничные дни не учитываются!

Не знаю, кому принадлежит этот алгоритм. Для меня он уже был народным. Здесь выкладываю большей частью и для себя, чтобы не забыть, но буду рад, если это пригодится кому-нибудь.

Часто возникает задача расчета просрочки платежа от даты реализации на текущую дату. Если речь идет о календарных днях, то все просто - это будет разность дат. Но если речь идет о банковских днях, то необходимо в таком расчете опираться на производственный календарь, который, естественно, предварительно необходимо будет заполнить.

Конкретно мы на нашем предприятии решали задачу просроченной задолженности в УТ 10.3. Там производственный календарь - это регистр сведений РегламентированныйПроизводственныйКалендарь.

Теперь привожу непосредственно алгоритм:

    ВЫБРАТЬ
        Календарь.ДатаКалендаря
    ПОМЕСТИТЬ БанковскиеДни
    ИЗ
        РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК Календарь
    ГДЕ
        Календарь.ДатаКалендаря >= &ДатаДокумента
        И Календарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
    ;
    
    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
        &ДатаДокумента КАК ДатаДокумента,
        БанковскиеДни.ДатаКалендаря КАК ДатаКалендаря,
        КОЛИЧЕСТВО(БанковскиеДни1.ДатаКалендаря) КАК НомерДняОтЗаданнойДаты
    ИЗ
        БанковскиеДни КАК БанковскиеДни
            ЛЕВОЕ СОЕДИНЕНИЕ БанковскиеДни КАК БанковскиеДни1
            ПО БанковскиеДни.ДатаКалендаря > БанковскиеДни1.ДатаКалендаря
    
    СГРУППИРОВАТЬ ПО
        БанковскиеДни.ДатаКалендаря

Так что получается на выходе этого запроса? А на выходе этого запроса получается таблица, состоящая из дат, исключая выходные дни, идущих в диапазоне от &ДатаДокумента до последней даты заполненного производственного календаря. Каждой такой дате будет соответствовать поле КоличествоДнейОтЗаданнойДаты, т.е от &ДатаДокумента. Приведем запрос и его результат на рисунке:

 

Теперь можно взять любую дату, сравнить ее с получившейся таблицей и узнать, какое количество банковских дней между &ДатаДокумента и любой из дат из результирующей таблицы. Правда, если датой из результирующей таблицы должен быть выходной, то придется пойти на какую-нибудь хитрость, поскольку выходные из этой таблицы исключены!

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Иван Петров (dgolovanov) 03.12.15 12:24
А почему Предпраздничный день не учитываете?
vladir; kite2; +2 Ответить 1
2. Сэр Артур (kite2) 03.12.15 15:49
(1) dgolovanov, На самом деле не только предпраздничный. У нас не учтены даже некоторые праздничные дни, потому что календарь мы заполняем по умолчанию. Но так вроде бы всех устраивало. Если честно я даже не очень хорошо понимаю, как учитывать предпраздничный день, это значит вычитать 1 час из общей суммы? Если так, то здесь играет роль понятие день, а не час. День 7 часов = дню 8 часов. У нас так принято.
3. Иван Петров (dgolovanov) 03.12.15 16:30
(2) kite2, Вы меня не поняли, наверное. Предпраздничный день на час короче, но он тоже рабочий, так сказать.
Например, пятница - предпраздничный день, работаем на час меньше. Но отбор только по рабочим дням нам скажет, что в неделе было 4 дня, а не 5. Т.е. один день, вполне себе рабочий, по в регистре являющийся предпраздничным - потеряем.
4. Сэр Артур (kite2) 03.12.15 16:47
(3) dgolovanov, Все, понял Вас!
Действительно, предпраздничные дни не учитываются в данном алгоритме.
За год работы от пользователей не поступало жалоб на это! Вы нашли баг, но думаю, что это нетрудно исправить в алгоритме, если предпраздничный день имеет реквизит, а он скорее всего имеет какой-то реквизит или другой признак.
В общем, не учитывали, потому что никто не обращал на это внимание :). Спасибо за замечание.
5. Иван Петров (dgolovanov) 03.12.15 18:06
Я просто для себя ваял такого плана алгоритм совсем недавно, решил сравнить. Там нечего исправлять-то:
| И Календарь.ВидДня В (
| ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий),
| ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный))

Просто может кому пригодится.
Stradivari; kite2; +2 Ответить 1
6. Сэр Артур (kite2) 03.12.15 19:10
(5) dgolovanov, Да, все очень просто.
7. Кириллов Денис (denver069) 12.01.16 07:04
Это примитивный вариант подходящий лишь для расчета показателя, например на форме документа. Как правило период просрочки рассчитывать нужно в отчете, а в отчете ДатаДокумента это не параметр, а поле таблицы.
8. Сэр Артур (kite2) 12.01.16 08:57
(7) denver069, Для того, о чем Вы говорите, используется связь по параметру в СКД между 2-я наборами данных. Но даже без СКД я придумал однажды как исхитриться, чтобы использовать этот алгоритм, когда дат много. Но это тема для отдельной статьи. Может позже я напишу ее. Сейчас пока нет времени.
9. Кириллов Денис (denver069) 12.01.16 10:33
(8) kite2, Настоятельно не рекомендую использовать в таких случаях связь наборов данных в СКД. Такие вещи вполне себе нормально делаются и в запросе с использованием производственного календаря и ранжирования исходной таблицы данных.
10. Сэр Артур (kite2) 12.01.16 14:22
(9) denver069, Прекрасно. Вот Ваше домашнее задание - напишите об этом статью.
11. Сэр Артур (kite2) 12.01.16 14:57
(9) denver069, Вообще говоря, это какой-то не программистский подход "рекомендую, не рекомендую". Технари так не мыслят. Технарь мыслит так, что надо, чтобы это работало. Если он что-то действительно не рекомендует, то способен внятно объяснить, почему он этого не рекомендует. И еще был очень сильный аргумент "примтивный вариант". E=mc^2 - это тоже очень примитивно по сравнению даже с определителем матрицы.
12. Роман Г (Stradivari) 27.09.16 17:09
Спасибо, пригодилось!
13. Сэр Артур (kite2) 28.09.16 08:19
(12) Stradivari, Я рад, что на мою страничку заходят не только тролли, но и люди, которым что-то надо на самом деле.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа