Как в СКД вывести товары без продаж с детализацией по всем дням периода

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

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

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

Способ 1. Формирование сетки дат и товаров через пакетный запрос

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

Разберем построение запроса по шагам:

  1. Выборка номенклатуры: отбираем нужный список номенклатурных позиций (исключая группы и помеченные на удаление элементы) во временную таблицу.
  2. Выборка дат периода: получаем список всех дней за период от &ДатаНачала до &ДатаОкончания из регистра сведений календаря (например, КалендарныеГрафики или ПроизводственныйКалендарь).
  3. Формирование матрицы: выполняем полное (декартово) соединение временной таблицы дат с таблицей товаров по условию ПО (ИСТИНА).
  4. Получение оборотов: соединяем полученную матрицу левым соединением с виртуальной таблицей РегистрНакопления.Продажи.Обороты одновременно по номенклатуре и по периоду.

Посмотрим на пример текста запроса:


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка
ПОМЕСТИТЬ ВТ_Номенклатура
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    НЕ Номенклатура.ЭтоГруппа
    И НЕ Номенклатура.ПометкаУдаления
{ГДЕ
    (Номенклатура.Ссылка В ИЕРАРХИИ (&НоменклатураИерархия))}

СГРУППИРОВАТЬ ПО
    Номенклатура.Ссылка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    КалендарныеГрафики.ДатаГрафика КАК ДатаГрафика
ПОМЕСТИТЬ ВТ_Даты
ИЗ
    РегистрСведений.КалендарныеГрафики КАК КалендарныеГрафики
ГДЕ
    КалендарныеГрафики.ДатаГрафика МЕЖДУ &ДатаНачала И &ДатаОкончания
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_Даты.ДатаГрафика КАК ДатаГрафика,
    ВТ_Номенклатура.Ссылка КАК Номенклатура
ПОМЕСТИТЬ ВТ_Сетка
ИЗ
    ВТ_Даты КАК ВТ_Даты
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Номенклатура КАК ВТ_Номенклатура
        ПО (ИСТИНА)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_Сетка.ДатаГрафика КАК ПериодДень,
    ВТ_Сетка.Номенклатура КАК Номенклатура,
    ЕСТЬNULL(ПродажиОбороты.КоличествоОборот, 0) КАК КоличествоОборот,
    ЕСТЬNULL(ПродажиОбороты.СуммаОборот, 0) КАК СуммаОборот
ИЗ
    ВТ_Сетка КАК ВТ_Сетка
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(
            {(&ДатаНачала)},
            {(&ДатаОкончания)},
            День,
            {Номенклатура В ИЕРАРХИИ (&НоменклатураИерархия)}
        ) КАК ПродажиОбороты
        ПО ВТ_Сетка.Номенклатура = ПродажиОбороты.Номенклатура
            И ВТ_Сетка.ДатаГрафика = ПродажиОбороты.Период

Обратите внимание: условие отбора по иерархии номенклатуры важно указывать как в секции выборки справочника, так и в параметрах виртуальной таблицы регистра. Это исключает избыточное чтение движений по позициям, которые не входят в целевую группу.

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

Если список номенклатуры велик или в конфигурации отсутствует готовый регистр календаря, декартово произведение в запросе может негативно сказаться на производительности СУБД. В этом случае эффективнее воспользоваться встроенным генератором периодов схемы компоновки данных.

Рассмотрим, как настроить отчет с помощью механизма дополнения периодов:

  1. Запрос набора данных: связываем справочник номенклатуры левым соединением с виртуальной таблицей оборотов без декартова произведения дат:
    
    ВЫБРАТЬ
        Номенклатура.Ссылка КАК Номенклатура,
        ПродажиОбороты.Период КАК ПериодДень,
        ПродажиОбороты.КоличествоОборот КАК КоличествоОборот,
        ПродажиОбороты.СуммаОборот КАК СуммаОборот
    ИЗ
        Справочник.Номенклатура КАК Номенклатура
            ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(
                {(&ДатаНачала)},
                {(&ДатаОкончания)},
                День,
                {Номенклатура В ИЕРАРХИИ (&НоменклатураИерархия)}
            ) КАК ПродажиОбороты
            ПО Номенклатура.Ссылка = ПродажиОбороты.Номенклатура
    ГДЕ
        НЕ Номенклатура.ЭтоГруппа
    {ГДЕ
        (Номенклатура.Ссылка В ИЕРАРХИИ (&НоменклатураИерархия))}
    
  2. Роль поля периода: на вкладке «Наборы данных» для поля ПериодДень проверяем корректность роли поля периода (тип ДополнительныйПериод или порядковый номер периода).
  3. Настройка структуры отчета:
    1. Создаем элемент структуры типа Таблица.
    2. В Строки добавляем группировку Номенклатура.
    3. В Колонки добавляем группировку ПериодДень.
  4. Настройка дополнения периода: в свойствах группировки колонок ПериодДень находим раздел «Дополнение периода» и задаем параметры:
    1. Тип дополнения: День.
    2. Начальная дата: &ДатаНачала.
    3. Конечная дата: &ДатаОкончания.

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

Отображение нулей вместо пустых значений (NULL)

Когда товар не продавался в определенный день, в результате левого соединения ресурсные поля принимают значение NULL. Чтобы в отчете выводились аккуратные нули, выполним следующие настройки:

  1. На вкладке «Ресурсы» для числовых полей укажем формулу с проверкой на пустое значение: ЕстьNull(Сумма(КоличествоОборот), 0) и ЕстьNull(Сумма(СуммаОборот), 0).
  2. На вкладке «Настройки» в разделе «Условное оформление» или в свойствах полей набора данных зададим формат числовых колонок: ЧН=0 (представление нуля).

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

← На главную