Как в СКД вывести отклонения остатков от лимитов по дням в одну строку

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

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

Разбор структуры запроса для получения данных

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

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


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

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


ВЫБРАТЬ
    Пределы.Номенклатура КАК Номенклатура,
    Пределы.Склад КАК Склад,
    Пределы.МинЗапас КАК МинЗапас,
    Пределы.МаксЗапас КАК МаксЗапас,
    Пределы.Период КАК Период
ПОМЕСТИТЬ ВТ_Пределы
ИЗ
    РегистрСведений.ПределыОстатковНоменклатуры КАК Пределы
;

Теперь объединим эти данные. Проанализируем ситуацию: нам нужно левое соединение остатков с пределами. Ключевой момент — сопоставление по дате. Если лимит установлен раз в месяц, а остатки мы смотрим каждый день, обычное соединение по равенству дат не сработает. В СКД это часто решается использованием виртуальных таблиц СрезПоследних, но внутри сложного запроса эффективнее использовать соединение по условию ПериодОстатков >= ПериодПределов с последующим выбором максимальной даты лимита.

Настройка структуры отчета в СКД

Выясним причину, почему данные «разлетаются» по разным строкам. Это происходит из-за того, что в группировках строк ошибочно присутствует поле Период. В СКД для кросс-отчетов необходимо использовать объект «Таблица» на вкладке «Настройки».

Рассмотрим пошаговую настройку структуры:

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

Вычисляемые поля для расчета отклонений

Чтобы отчет выводил разницу (например, «+1» или «-2»), проанализируем использование Вычисляемых полей. Это позволит нам не перегружать запрос математической логикой.

Создадим поле Отклонение. В выражении напишем формулу, учитывающую оба порога. Посмотрим на пример выражения:


ВЫБОР 
    КОГДА ЕстьNull(Остаток, 0) > ЕстьNull(МаксимальныйЗапас, 999999) 
        ТОГДА Остаток - МаксимальныйЗапас 
    КОГДА ЕстьNull(Остаток, 0) < ЕстьNull(МинимальныйЗапас, 0) 
        ТОГДА Остаток - МинимальныйЗапас 
    ИНАЧЕ 0 
КОНЕЦ

Важный момент: использование функции ЕстьNull обязательно. Если для товара не задан МаксимальныйЗапас, а мы попытаемся вычесть его из остатка, результатом будет NULL, и ячейка в отчете останется пустой.

Условное оформление для наглядности

Чтобы отчет выглядел профессионально, как в примере автора (с префиксами «+» и «-»), воспользуемся вкладкой «Условное оформление»:

  1. Добавьте новое правило для поля Отклонение.
  2. В условии укажите: Отклонение Больше 0.
  3. В оформлении выберите «Формат» и в строке формата числового значения укажите префикс +. Также можно задать цвет текста (например, синий).
  4. Создайте второе правило: Отклонение Меньше 0. Здесь можно задать красный цвет текста.
  5. Создайте третье правило: Отклонение Равно 0. В оформлении выберите «Текст» и оставьте его пустым, чтобы не загромождать отчет нулями там, где остатки в норме.

Использование функций СКД для итогов

Не забудьте настроить вкладку «Ресурсы». Для полей Остаток, МинимальныйЗапас и МаксимальныйЗапас обычно используется функция СУММА(ИмяПоля) или МАКСИМУМ(ИмяПоля). Если вы используете «СрезПоследних», то для ресурсов МинЗапас и МаксЗапас лучше использовать МАКСИМУМ, чтобы при группировке по складу значения не суммировались некорректно.

Проанализировав ситуацию с «размножением» строк, мы видим, что правильное распределение полей между строками таблицы и выбранными полями группировок полностью решает проблему. Теперь данные по «Товару 1» будут занимать ровно одну строку, а все отклонения по дням выстроятся в аккуратный ряд в соответствующих колонках дат.

← На главную