При разработке отчетов в системе 1С:Предприятие 8.3 часто возникает задача вывода данных не просто в хронологическом порядке (по дням, неделям или месяцам), а в разрезе произвольных интервалов, которые пользователь задает самостоятельно. Стандартные механизмы группировок СКД по периодам (например, Дополнение) здесь не всегда справляются, так как они ориентированы на фиксированную кратность. В данной статье мы разберем несколько эффективных способов реализации этой задачи: от динамического формирования текста запроса до использования внешних наборов данных.
Рассмотрим ситуацию, когда пользователю на форме предоставляется таблица, где он указывает пары дат: НачалоПериода и КонецПериода. Для того чтобы СКД поняла, к какому интервалу относится запись из регистра, мы можем программно сконструировать текст запроса, который создаст виртуальную таблицу периодов.
Проанализируем алгоритм действий:
ВЫБРАТЬ ... ОБЪЕДИНИТЬ ВСЕ.Пример кода для генерации текста запроса:
ТекстВТПериоды = "";
Для Каждого СтрокаПериода Из ТаблицаПериодов Цикл
Если Не ПустаяСтрока(ТекстВТПериоды) Тогда
ТекстВТПериоды = ТекстВТПериоды + " ОБЪЕДИНИТЬ ВСЕ ";
КонецЕсли;
ТекстВТПериоды = ТекстВТПериоды +
"ВЫБРАТЬ ДАТАВРЕМЯ(" + Формат(СтрокаПериода.ДатаНачала, "ДФ=yyyy,M,d,H,m,s") + ") КАК ДатаС, " +
"ДАТАВРЕМЯ(" + Формат(СтрокаПериода.ДатаОкончания, "ДФ=yyyy,M,d,H,m,s") + ") КАК ДатаПо, " +
"'" + СтрокаПериода.Наименование + "' КАК ИмяПериода";
КонецЦикла;
Полученную таблицу ВТПериоды мы соединяем в основном запросе с таблицей данных (например, РегистрСведений.Вызовы) по условию вхождения даты записи в интервал: Вызовы.Период МЕЖДУ ВТПериоды.ДатаС И ВТПериоды.ДатаПо. Таким образом, каждая запись получит атрибут ИмяПериода, который мы выведем в колонки таблицы СКД.
Если периодов много или логика их формирования сложная, удобнее использовать внешний набор данных. В схеме компоновки данных (СКД) мы создаем набор данных типа Объект и называем его, например, ТаблицаПериодов.
Разберем, как настроить связи в этом случае:
ДатаНачала, ДатаОкончания и НаименованиеИнтервала.ДатаЗаписи >= ДатаНачала И ДатаЗаписи <= ДатаОкончания.Важный нюанс: чтобы в отчете отобразились даже те периоды, по которым не было движений, необходимо сделать левое соединение от таблицы периодов. В СКД это достигается правильным выбором ведущего набора данных в группировках настроек. Если мы выносим НаименованиеИнтервала в колонки, СКД автоматически построит сетку по всем строкам из внешнего набора данных.
Выясним причину, по которой этот метод считается самым простым, но менее гибким. Он подходит, если количество интервалов фиксировано (например, всегда 5 частей месяца). Мы можем создать в СКД вычисляемое поле ИнтервалДляКолонки.
Выражение для такого поля будет выглядеть следующим образом:
ВЫБОР
КОГДА Период МЕЖДУ &Начало1 И &Конец1 ТОГДА &Имя1
КОГДА Период МЕЖДУ &Начало2 И &Конец2 ТОГДА &Имя2
КОГДА Период МЕЖДУ &Начало3 И &Конец3 ТОГДА &Имя3
ИНАЧЕ "Прочее"
КОНЕЦ
В параметрах СКД (&Начало1, &Конец1 и т.д.) пользователь сможет указать нужные даты. Однако этот метод требует заранее предопределенного количества параметров в схеме, что не всегда удобно для динамических задач.
Рассмотрим более профессиональный подход, используемый в типовых конфигурациях для анализа дебиторской задолженности. Создается вспомогательный справочник (или таблица в памяти) ВариантыКлассификацииИнтервалов. Каждая настройка содержит табличную часть с границами периодов.
Посмотрим на пример логики в запросе:
ГДЕ или ВЫБОР для определения принадлежности.Преимущество этого метода: пользователь может сохранять разные настройки разбиения (например, "По декадам", "По рабочим неделям", "Срочный отчет") и быстро переключаться между ними, не вводя даты вручную каждый раз.
Чтобы отчет выглядел как в Excel, необходимо правильно настроить вкладку Настройки в компоновщике:
Водитель, Компания).ИмяИнтервала или НаименованиеПериода).СуммаКоличествоЗапросов).Важно: для корректного отображения временных границ рекомендуем использовать в запросе функцию КОНЕЦПЕРИОДА(Вызовы.Период, ДЕНЬ), чтобы избежать проблем с попаданием записей, сделанных в последнюю секунду дня, если пользователь указал дату без учета времени.
Таким образом, комбинируя программную подготовку данных (формирование ТЗ периодов) и возможности СКД по связи наборов данных, мы получаем мощный инструмент, позволяющий строить отчеты любой сложности с динамически изменяемой структурой колонок.