При разработке отчетов в 1С программисты часто сталкиваются с ситуацией, когда стандартная выборка по документам не позволяет получить полную картину за период. Например, если документы создавались не каждый день, обычный запрос «пропустит» пустые даты, что сделает невозможным расчет средних показателей или учет календарных категорий (выходных, определенных интервалов дней недели). В этой статье мы разберем, как сформировать полную последовательность дат в запросе, классифицировать их и правильно настроить Систему компоновки данных (СКД) для расчета итогов.
Рассмотрим ситуацию: нам нужно получить количество дней в месяце, разделенных на категории (например, «Понедельник-Среда», «Четверг-Пятница» и «Суббота-Воскресенье»). Если мы будем строить запрос напрямую к таблице документов, то получим только те дни, в которых были движения. Если за месяц было всего три документа, запрос покажет три дня, хотя в периоде их тридцать. Для решения этой задачи нам необходимо сначала создать «сетку» из всех дат периода, а уже к ней присоединять данные документов.
Проанализируем классический способ генерации последовательности чисел, который позволяет получить любое количество строк в запросе без обращения к реальным таблицам базы данных. Мы создаем временную таблицу из десяти цифр (от 0 до 9) и перемножаем её саму на себя несколько раз.
Разберем по шагам создание такой таблицы:
ВЫБРАТЬ 0 КАК Цифра ПОМЕСТИТЬ ТабЦифр ОБЪЕДИНИТЬ ВЫБРАТЬ 1 ОБЪЕДИНИТЬ ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВЫБРАТЬ 3 ОБЪЕДИНИТЬ ВЫБРАТЬ 4 ОБЪЕДИНИТЬ ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВЫБРАТЬ 6 ОБЪЕДИНИТЬ ВЫБРАТЬ 7 ОБЪЕДИНИТЬ ВЫБРАТЬ 8 ОБЪЕДИНИТЬ ВЫБРАТЬ 9;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, т1.Цифра + 10 * т2.Цифра + 100 * т3.Цифра) КАК Дата
ПОМЕСТИТЬ ВТ_ВсеДаты
ИЗ
ТабЦифр КАК т1,
ТабЦифр КАК т2,
ТабЦифр КАК т3
ГДЕ
ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, т1.Цифра + 10 * т2.Цифра + 100 * т3.Цифра) <= &КонецПериода
В данном примере мы соединяем три таблицы цифр, что дает нам 1000 комбинаций (строк). Этого достаточно, чтобы покрыть период почти в три года. Функция ДОБАВИТЬКДАТЕ последовательно прибавляет к начальной дате количество дней, равное порядковому номеру строки. Важно: не забудьте ограничить выборку условием ГДЕ, чтобы не выйти за рамки конечной даты периода.
Если в вашей конфигурации (ЗУП, ERP, КА, БП) ведется производственный календарь, задачу можно решить еще проще. Существует регистр сведений ДанныеПроизводственногоКалендаря, который уже содержит все даты. Рассмотрим пример запроса к нему:
ВЫБРАТЬ
Календарь.Дата КАК ПериодДень,
ВЫБОР
КОГДА ДЕНЬНЕДЕЛИ(Календарь.Дата) МЕЖДУ 1 И 3 ТОГДА "Пн-Ср"
КОГДА ДЕНЬНЕДЕЛИ(Календарь.Дата) МЕЖДУ 4 И 5 ТОГДА "Чт-Пт"
ИНАЧЕ "Сб-Вс"
КОНЕЦ КАК КатегорияДня
ИЗ
РегистрСведений.ДанныеПроизводственногоКалендаря КАК Календарь
ГДЕ
Календарь.Дата МЕЖДУ &НачалоПериода И &КонецПериода
Этот способ предпочтительнее, так как система сразу предоставляет информацию о праздниках и переносах выходных. Мы используем функцию ДЕНЬНЕДЕЛИ, чтобы классифицировать каждый день по нужным нам категориям.
Теперь, когда у нас есть временная таблица со всеми датами и их категориями, мы должны выполнить Левое Соединение нашей таблицы дат с таблицей документов. Проанализируем структуру итогового запроса:
Дата и КатегорияДня из нашей временной таблицы календаря.НАЧАЛОПЕРИОДА(Документ.Дата, ДЕНЬ) = ВТ_ВсеДаты.Дата.КатегорияДня.КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Дата).Такой подход гарантирует, что даже если за категорию "Сб-Вс" не было ни одного документа, в отчете все равно отобразится количество выходных дней в этом месяце (например, 8 или 9), а сумма по документам будет равна нулю.
Вторая проблема, поднятая в обсуждении — расчет показателей по-разному для разных уровней иерархии (например, для Подразделения и Отдела). В СКД это решается на закладке Ресурсы.
Выясним, как настроить индивидуальные расчеты:
КоличествоДней).Сумма(КоличествоДней).Отдел.Максимум(КоличествоДней).Подразделение.Таким образом, СКД будет применять разные математические алгоритмы в зависимости от того, на каком уровне иерархии выводится строка. Это позволяет избежать неверного суммирования календарных дней на верхних уровнях, где нам, возможно, нужно среднее значение или максимум, а не сумма всех дней всех подотделов.
Иногда при использовании вычисляемых категорий (как "Пн-Ср") нарушается порядок вывода колонок или строк. Посмотрим, почему стандартная сортировка может не работать. СКД часто игнорирует УПОРЯДОЧИТЬ ПО в тексте запроса, отдавая приоритет настройкам на вкладке Настройки - Сортировка.
Чтобы зафиксировать порядок категорий:
ПорядокКатегории (например, 1 для "Пн-Ср", 2 для "Чт-Пт" и т.д.).Проанализировав эти методы, мы видим, что связка правильно сгенерированного календаря в запросе и гибкой настройки ресурсов в СКД позволяет решать самые сложные задачи по аналитике периодов, обеспечивая точность данных даже при отсутствии первичных документов в отдельные дни.