Как в СКД дополнить таблицу периодов нулевыми остатками?

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

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

Причина «исчезновения» строк в отчетах СКД

Проанализируем ситуацию: когда мы используем виртуальную таблицу Остатки с передачей параметра &Период, платформа обращается к итогам регистра накопления. Если на конкретную дату (например, на конец месяца) итоговая запись по паре «Номенклатура — Склад» равна нулю, и по ней не было движений, таблица может не вернуть строку вовсе. При использовании соединения наборов данных, если в «ведущем» наборе нет записи на эту дату, то и в итоговый результат она не попадет. Наша задача — создать структуру, которая гарантирует наличие строки периода для каждой значимой единицы номенклатуры.

Решение 1: Настройка ролей полей периода в СКД

Это наиболее правильный «штатный» способ решения проблемы внутри системы компоновки данных. СКД обладает встроенным механизмом генерации недостающих периодов (дополнения). Разберем по шагам, как его активировать:

  1. Откроем схему компоновки данных и перейдем на вкладку Наборы данных.
  2. Найдем поле, отвечающее за период (например, ПериодДляВывода или Дата).
  3. В колонке Роль нажмем на кнопку редактирования.
  4. В открывшемся окне настройки роли поля убедимся, что параметр Без дополнения выключен (флажок снят).
  5. Установим Тип дополнения (например, Месяц, День или Год в зависимости от требуемой детализации).
  6. Укажем Начальную дату и Конечную дату дополнения. Обычно здесь используются параметры отчета: &НачалоПериода и &КонецПериода.

Благодаря этим настройкам СКД самостоятельно проанализирует выборку и, если для какой-то группировки пропущен месяц внутри интервала, она программно добавит строку с этой датой и нулевыми ресурсами.

Решение 2: Использование оборотов для формирования списка номенклатуры

Если мы не хотим выводить абсолютно всю номенклатуру из справочника (что привело бы к огромному количеству пустых строк), но нам нужны те позиции, которые «оживали» в выбранном периоде, применим метод предварительного отбора. Рассмотрим пример запроса, который собирает «скелет» данных:


ВЫБРАТЬ РАЗЛИЧНЫЕ
    Обороты.Номенклатура КАК Номенклатура
ПОМЕСТИТЬ ВТ_НужнаяНоменклатура
ИЗ
    РегистрНакопления.ПартииТоваровНаСкладах.Обороты(&НачалоПериода, &КонецПериода, Авто, ) КАК Обороты

ОБЪЕДИНИТЬ

ВЫБРАТЬ РАЗЛИЧНЫЕ
    Остатки.Номенклатура
ИЗ
    РегистрНакопления.ПартииТоваровНаСкладах.Остатки(&НачалоПериода, ) КАК Остатки
;

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

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

Решение 3: Виртуальная таблица «Остатки и обороты»

Вместо ручного соединения таблиц остатков на разные даты, мы можем использовать виртуальную таблицу ОстаткиИОбороты. Проанализируем её параметры: у неё есть возможность настройки метода дополнения периодов. Если в настройках виртуальной таблицы указать периодичность (например, Месяц) и метод дополнения ДвиженияИГраницыПериода, система сама вернет записи на границы периодов, даже если остаток стал нулевым.

При этом в СКД важно правильно настроить ресурсы. Чтобы вместо пустого значения отображался ноль, используем выражение в поле ресурса:

ЕСТЬNULL(СУММА(КоличествоОстаток), 0)

Решение 4: Соединение наборов данных по параметру

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

Чтобы этого избежать, выполним следующие действия:

  1. Первый набор данных (Набор1) должен содержать полный список дат и номенклатуры.
  2. Второй набор данных (Набор2) — это запрос к остаткам с параметром &Период.
  3. В Связях наборов данных укажем Набор1 как источник, а Набор2 как приемник.
  4. В качестве условия связи передадим поле даты из Набора1 в параметр Период Набора2.
  5. Обязательно используем Левое соединение (в интерфейсе связей это обеспечивается тем, что Набор1 является ведущим).

Это гарантирует, что для каждой даты из первого списка будет предпринята попытка получить остаток. Если остатка нет, СКД выведет NULL, который мы заменим на 0 через настройки ресурсов или условное оформление.

Итоги и рекомендации

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

← На главную