Как в отчете СКД вывести все дни периода при отсутствии продаж и движений

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При разработке аналитических отчетов в системе компоновки данных (СКД), таких как динамика продаж и остатков по дням, разработчики часто сталкиваются с ситуацией, когда дни без движений исчезают из результирующей кросс-таблицы или отчета. Даже если в запрос добавляется сгенерированная таблица дат (календарь), при объединении с реальными регистрами пустые даты могут отсекаться или группироваться некорректно.

Проанализируем причины такого поведения платформы 1С и разберем несколько проверенных способов отображения полного календаря в отчетах СКД.

Почему пропадают даты без движений

Выясним, какие механизмы СКД влияют на скрытие колонок или строк с пустыми периодами:

  1. Особенности группировок со значениями NULL. При левом соединении таблицы дат с таблицей движений для дней без операций поля номенклатуры, складов и характеристик принимают значение NULL. При выводе иерархии строк СКД выносит такие строки в отдельную пустую группу либо исключает их из дерева номенклатуры, из-за чего сопоставление даты с товаром нарушается.
  2. Сворачивание пустых колонок таблицы. Если в колонках кросс-таблицы выводится группировка по периоду, для которого нет ни одного числового значения ресурса (или ресурс равен NULL), компоновщик макета по умолчанию считает колонку не несущей полезной информации и не выводит ее.
  3. Ограничения виртуальной таблицы ОстаткиИОбороты. Виртуальная таблица регистра накопления при периодичности День дополняет периоды только для тех комбинаций измерений, по которым были движения внутри заданного интервала. Если движений по товару не было вовсе, виртуальная таблица не вернет записей.
  4. Несовпадение границ времени. Если дата календаря приведена к началу дня (00:00:00), а движения регистрируются внутри дня или сравниваются с концом периода дня (23:59:59), условие соединения по равенству дат не срабатывает.

Способ 1. Использование штатного механизма дополнения периодов в СКД

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

Разберем настройку по шагам:

  1. Настройка роли поля периода в наборе данных. В схеме компоновки данных на вкладке Наборы данных найдем поле периода (например, ПериодДень). В колонке Роль укажем флаг Период и зададим соответствующий тип (День).
  2. Включение автодополнения в структуре отчета. Перейдем на вкладку Настройки. В структуре отчета выберем группировку колонок по полю ПериодДень. На вкладке Дополнительно (в свойствах группировки) установим:
    1. Тип дополнения: День;
    2. Начальный период: параметр &НачалоПериода;
    3. Конечный период: параметр &КонецПериода.
  3. Инициализация ресурсов. Чтобы пустые пересечения строк и колонок отображались корректно, на вкладке Ресурсы опишем выражение для вычисления суммы с защитой от пустых значений: ЕстьNULL(Сумма(КоличествоОборот), 0)

Способ 2. Разделение на два набора данных и связь в схеме

Если отчет совмещает сложную иерархию справочников и агрегированные регистры, эффективным решением является разделение выборки на два независимых набора данных с последующей связью средствами СКД.

Рассмотрим структуру такого отчета:

  1. НаборДанных1 (Список аналитики). Простой запрос к справочнику Номенклатура или таблице остатков, возвращающий список товаров и складов, которые должны гарантированно попасть в отчет.
  2. НаборДанных2 (Продажи и движения). Запрос к регистру накопления ВыручкаИСебестоимостьПродаж или ТоварыНаСкладах с детализацией по периоду (день).
  3. Вкладка «Связи наборов данных». Установим связь от источника НаборДанных1 к приемнику НаборДанных2 по полям номенклатуры и характеристик.
  4. В структуре отчета в строки выведем поля из НаборДанных1, а в колонки — поле даты из НаборДанных2 с включенным дополнением периодов. СКД автоматически построит полную сетку по всем товарам.

Способ 3. Построение матрицы «Номенклатура x Календарь» в запросе

Если логика отчета требует подготовки всех данных строго внутри одного комплексного запроса с временными таблицами, применим формирование полной координатной сетки (декартово произведение).

Разберем логику построения такого запроса:

  1. Формируем временную таблицу уникальных товаров ВТ_Товары.
  2. Формируем временную таблицу всех календарных дней диапазона ВТ_Календарь, приводя даты строго к началу дня с помощью функции НАЧАЛОПЕРИОДА(..., ДЕНЬ).
  3. Создаем полную сетку сочетаний каждого товара с каждым днем периода через перекрестное соединение:
    
    ВЫБРАТЬ
        ВТ_Товары.Номенклатура КАК Номенклатура,
        ВТ_Календарь.Дата КАК ПериодДень
    ПОМЕСТИТЬ ВТ_Сетка
    ИЗ
        ВТ_Товары КАК ВТ_Товары
        СОЕДИНЕНИЕ ВТ_Календарь КАК ВТ_Календарь
            ПО ИСТИНА
    ;
    
  4. К полученной сетке ВТ_Сетка выполняем левое соединение с временной таблицей фактических продаж и остатков:
    
    ВЫБРАТЬ
        Сетка.Номенклатура КАК Номенклатура,
        Сетка.ПериодДень КАК ПериодДень,
        ЕСТЬNULL(Продажи.КоличествоОборот, 0) КАК Количество
    ИЗ
        ВТ_Сетка КАК Сетка
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Продажи КАК Продажи
            ПО Сетка.Номенклатура = Продажи.Номенклатура
            И Сетка.ПериодДень = Продажи.ПериодДень
    

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

← На главную