Не дает мне покоя задача, успешно решенная в прошлый раз. Кратко напомню, о чем речь.
Есть некая табличка с данными за несколько лет. Сделал по этим данным отчет в СКД в виде графиков по месяцам.
Посмотрел на результат – что-то тесновато на шкале. Надо бы поделить по годам.
Поделил – стало гораздо лучше. Но поскольку нынешний год только начался, самая свежая часть графика получилась так себе.
Тогда решил поделить графики не по календарным годам, а по периодам в год, отсчитывая их назад от текущего момента.
Отличное решение.
Вот тут радостно хлопаем в ладоши.
А потом пролистываем отчет до конца.
Э-э-э… Надо бы еще подумать над оформлением. Конечно, все зависит от объема данных, но у меня такая картинка будет постоянно, потому что в табличке данные не просто за несколько лет, а еще за 2 месяца впридачу. Не спрашивайте, почему. Так надо.
И тут в голову пришла очередная идея – почему бы не присоединять такой короткий участок к соседнему? Тому пара лишних месяцев не повредит, зато график не утратит наглядность.
Чтобы долго не рассуждать, сразу выложу решение. Как и в прошлый раз, это дополнение к основному запросу отчета.
А короткий участок в самом начале графика отныне будет именоваться КУ.
…
ГОД(ВТОтчет.Месяц) КАК Год
ПОМЕСТИТЬ ВТсГодом
ИЗ
ВТОтчет КАК ВТОтчет
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
МИНИМУМ(ВТОтчет.Месяц) КАК НачалоДата,
МАКСИМУМ(ВТОтчет.Месяц) КАК КонецДата
ПОМЕСТИТЬ ВТМинМакс
ИЗ
ВТОтчет КАК ВТОтчет
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
МЕСЯЦ(ВТМинМакс.НачалоДата) КАК НачалоМесяц,
МЕСЯЦ(ВТМинМакс.КонецДата) КАК КонецМесяц,
ГОД(ВТМинМакс.НачалоДата) КАК НачалоГод,
ГОД(ВТМинМакс.КонецДата) КАК КонецГод
ПОМЕСТИТЬ ВТГраницы
ИЗ
ВТМинМакс КАК ВТМинМакс
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТГраницы.КонецМесяц - ВТГраницы.НачалоМесяц + 1 +
ВЫБОР
КОГДА ВТГраницы.КонецМесяц < ВТГраницы.НачалоМесяц
ТОГДА 12
ИНАЧЕ 0
КОНЕЦ КАК КУМесяцы
ПОМЕСТИТЬ ВТРазмеры
ИЗ
ВТГраницы КАК ВТГраницы
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(ВТМинМакс.НачалоДата, МЕСЯЦ, 12) <= ВТМинМакс.КонецДата
И ВТРазмеры.КУМесяцы < 3 КАК ФлагМожноИНужно,
ДОБАВИТЬКДАТЕ(ВТМинМакс.НачалоДата, МЕСЯЦ, ВТРазмеры.КУМесяцы) КАК КУГраница
ПОМЕСТИТЬ ВТКритерии
ИЗ
ВТМинМакс КАК ВТМинМакс,
ВТРазмеры КАК ВТРазмеры
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТсГодом.Месяц,
ВТсГодом.Приход,
ВТсГодом.Расход,
ВТсГодом.Год,
ВТсГодом.Год +
ВЫБОР
КОГДА МЕСЯЦ(ВТсГодом.Месяц) > ВТГраницы.КонецМесяц
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ +
ВЫБОР
КОГДА ВТКритерии.ФлагМожноИНужно
И ВТсГодом.Месяц < ВТКритерии.КУГраница
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ КАК Период
ИЗ
ВТсГодом КАК ВТсГодом,
ВТГраницы КАК ВТГраницы,
ВТКритерии КАК ВТКритерии
Временных таблиц стало еще больше, но лучше так, чем сойти с ума от формул. А теперь комментарии.
ВТРазмеры.КУМесяцы – это количество месяцев в том самом КУ, то есть количество точек на шкале. Если оно меньше 3 (к примеру), присоединение имеет смысл. Это условие «нужно».
А еще есть условие «можно». Ведь если график целиком укладывается в КУ, его и присоединять-то некуда. В данном случае исходим из того, что происходит группировка по периодам продолжительностью в год с отсчетом от конца графика. Значит, если КУ – не единственный фрагмент, то должен быть еще хотя бы один полный период.
Вот и получается условие: если крайние даты отстоят друг от друга не менее чем на год (условие «можно»), а в КУ меньше 3 точек (условие «нужно»), присоединение состоится.
Технически присоединение КУ – это увеличение номера года, означающего период, для всех месяцев, составляющих КУ. Именно это и происходит во втором выражении ВЫБОР в последнем запросе пакета.
Кстати, ВТКритерии.КУГраница – это дата начала месяца, с которого начинается период, следующий за КУ. Напоминаю, что в данных для отчета месяцы обозначены датой их начала.
А ВТГраницы.НачалоМесяц и ВТГраницы.КонецМесяц – это номера месяцев в году. Тут важно не путать интервалы между датами и точки на шкале.
Между прочим, проблема КУ существует и при группировке по годам. Никто ведь не обещал, что график не начнется с декабря.
Более того, если брать произвольные данные, а не отмеренные строго по годам, то на обоих концах графика чаще всего будут неполные годы. Вообще-то, именно ради устранения КУ в конце графика и была придумана группировка по периодам. Однако может потребоваться график с группировкой по годам, но без таких вот картинок в январе:
И еще важно решить, что делать, если весь график состоит только из двух КУ. Что к чему присоединять? Короткий к длинному? Или прошлый год к нынешнему? Пока принято решение в такой ситуации выбирать текущий год. Мы же из него смотрим на график.
Ниже вариант запроса для группировки по годам. Показаны только отличия, которые начинаются с таблицы ВТРазмеры.
…
ВЫБРАТЬ
12 - ВТГраницы.НачалоМесяц + 1 КАК НачалоКУМесяцы,
ВТГраницы.КонецМесяц КАК КонецКУМесяцы
ПОМЕСТИТЬ ВТРазмеры
ИЗ
ВТГраницы КАК ВТГраницы
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТГраницы.КонецГод > ВТГраницы.НачалоГод
И ВТРазмеры.НачалоКУМесяцы < 3 КАК НачалоФлаг,
ВТГраницы.КонецГод > ВТГраницы.НачалоГод
И ВТРазмеры.КонецКУМесяцы < 2 КАК КонецФлаг,
ДОБАВИТЬКДАТЕ(ВТМинМакс.НачалоДата, МЕСЯЦ, ВТРазмеры.НачалоКУМесяцы) КАК НачалоКУГраница,
НАЧАЛОПЕРИОДА(ВТМинМакс.КонецДата, ГОД) КАК КонецКУГраница
ПОМЕСТИТЬ ВТКритерииПред
ИЗ
ВТМинМакс КАК ВТМинМакс,
ВТГраницы КАК ВТГраницы,
ВТРазмеры КАК ВТРазмеры
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТКритерииПред.НачалоФлаг,
ВЫБОР
КОГДА ВТКритерииПред.НачалоФлаг
И ВТКритерииПред.КонецФлаг
И ВТГраницы.КонецГод - ВТГраницы.НачалоГод = 1
ТОГДА ЛОЖЬ
ИНАЧЕ ВТКритерииПред.КонецФлаг
КОНЕЦ КАК КонецФлаг,
ВТКритерииПред.НачалоКУГраница,
ВТКритерииПред.КонецКУГраница
ПОМЕСТИТЬ ВТКритерии
ИЗ
ВТГраницы КАК ВТГраницы,
ВТКритерииПред КАК ВТКритерииПред
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТсГодом.Месяц,
ВТсГодом.Приход,
ВТсГодом.Расход,
ВТсГодом.Год +
ВЫБОР
КОГДА ВТКритерии.НачалоФлаг
И ВТсГодом.Месяц < ВТКритерии.НачалоКУГраница
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ –
ВЫБОР
КОГДА ВТКритерии.КонецФлаг
И ВТсГодом.Месяц >= ВТКритерии.КонецКУГраница
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ КАК Год,
ВТсГодом.Год КАК Период
ИЗ
ВТсГодом КАК ВТсГодом,
ВТКритерии КАК ВТКритерии
Кстати, именно ради этого варианта в таблице ВТГраницы вычисляются поля НачалоГод и КонецГод. При группировке по периодам они не нужны. Но тут особо нечего оптимизировать, так что все поля оставлены для единообразия.
Ну, и «+1» в самом начале этого фрагмента оставлено для наглядности. Оно напоминает, что речь идет о количестве точек на шкале, а не об интервалах между датами.
Вот, собственно, и все.