Недавно натолкнулся на статью, где предлагается метод вырезания из нужных периодов периоды-исключения с помощью кода встроенного языка 1С. Но часто бывает, что периоды надо обрабатывать в запросах, и, чтобы не прерывать выполнение запроса, передавать периоды в ТЗ, обрабатывать их в ТЗ, затем снова помещать в запрос, предлагается достаточно несложный алгоритм, с помощью которого можно объединять и исключать периоды в любых отношениях, в. т.ч. можно слить множество периодов, идущих друг за другом, а также удалять периоды, когда в остатке получается 1 день.
Суть метода такова:
- готовим числовой ряд;
- разбиваем периоды на дни;
- {если удаляем периоды} разбиваем исключаемые периоды на дни;
- {если удаляем периоды} оставляем только дни из исходных периодов;
- находим промежутки между оставшимися соседними днями;
- получаем минимальный и максимальный день из исходных дней {или из оставшихся дней}, т.е. крайние границы диапазонов;
- даты начал периодов соберем из минимальной границы и конечных дат промежутков;
- даты концов периодов соберем из максимальной границы и начальных дат промежутков;
- сгруппируем попарно даты начал и даты концов;
- profit!
Кому лень кодить - берите и юзайте полностью открытый код из обработки. (Проверено на платформе 8.3.20, но будет работать и на 8.2+)
Небольшие тонкости: алгоритм из коробки будет работать для заполненных и правильных периодов, т.к. числовой ряд рассчитан на диапазон в ~180 лет, т.е. пустую дату надо заменять, например на 01.01.1900 (вряд ли кто-то ведёт бизнес с более ранней даты), и должно выполняться условие (ДатНач<=ДатКон). Конечно, можно расширить числовой ряд до 2^20 (или еще больше), чтобы охватывать '00010101', но тогда запрос будет выполняться несколько секунд.
Пример проверки объединения периодов:
Пример проверки исключения периодов:
P.S. Может, это и боян, но с наскока не удалось найти подобных реализаций на данном портале именно с помощью запросов...