При разработке отчетов для анализа складских запасов программисты часто сталкиваются с задачей вывода данных в виде кросс-таблицы: когда в строках отображаются товары, а в колонках — даты. Одной из типичных проблем является «размытие» данных, когда показатели одного и того же товара за разные дни попадают в разные строки. Рассмотрим подробнее, как правильно сконструировать такой отчет в Системе компоновки данных (СКД), чтобы получить компактную и информативную таблицу с отклонениями от минимальных и максимальных порогов.
Для начала нам необходимо подготовить данные. Проблема автора заключалась в том, что данные из регистра накопления (остатки) и регистра сведений (пороги) нужно корректно сопоставить на каждую дату периода. Разберем пример запроса, который позволяет собрать информацию во временные таблицы для последующего анализа.
Первым шагом сформируем таблицу фактических остатков. Важно сгруппировать данные по дням, чтобы иметь точку привязки для каждой даты отчета:
ВЫБРАТЬ
НАЧАЛОПЕРИОДА(ОстаткиТоваров.Период, ДЕНЬ) КАК Период,
ОстаткиТоваров.Склад КАК Склад,
ОстаткиТоваров.Номенклатура КАК Номенклатура,
СУММА(ОстаткиТоваров.Количество) КАК Количество
ПОМЕСТИТЬ ВТ_Остатки
ИЗ
РегистрНакопления.ОстаткиТоваровНаСкладах КАК ОстаткиТоваров
ГДЕ
ОстаткиТоваров.Период МЕЖДУ &НачалоПериода И &КонецПериода
СГРУППИРОВАТЬ ПО
ОстаткиТоваров.Склад,
ОстаткиТоваров.Номенклатура,
НАЧАЛОПЕРИОДА(ОстаткиТоваров.Период, ДЕНЬ)
;
Вторым шагом получим установленные лимиты (минимальный и максимальный запас). Поскольку лимиты могут меняться со временем, нам нужно знать актуальное значение на каждый день. Однако для упрощения на первом этапе можно выгрузить все записи регистра за период во временную таблицу:
ВЫБРАТЬ
Пределы.Номенклатура КАК Номенклатура,
Пределы.Склад КАК Склад,
Пределы.МинЗапас КАК МинЗапас,
Пределы.МаксЗапас КАК МаксЗапас,
Пределы.Период КАК Период
ПОМЕСТИТЬ ВТ_Пределы
ИЗ
РегистрСведений.ПределыОстатковНоменклатуры КАК Пределы
;
Теперь объединим эти данные. Проанализируем ситуацию: нам нужно левое соединение остатков с пределами. Ключевой момент — сопоставление по дате. Если лимит установлен раз в месяц, а остатки мы смотрим каждый день, обычное соединение по равенству дат не сработает. В СКД это часто решается использованием виртуальных таблиц СрезПоследних, но внутри сложного запроса эффективнее использовать соединение по условию ПериодОстатков >= ПериодПределов с последующим выбором максимальной даты лимита.
Выясним причину, почему данные «разлетаются» по разным строкам. Это происходит из-за того, что в группировках строк ошибочно присутствует поле Период. В СКД для кросс-отчетов необходимо использовать объект «Таблица» на вкладке «Настройки».
Рассмотрим пошаговую настройку структуры:
Склад, а внутрь неё — группировку по полю Номенклатура.Период. В свойствах этой группировки на вкладке «Тип дополнения» выберите «День», чтобы отчет вывел все даты периода, даже если в какой-то из дней не было движений.МинЗапас и МаксЗапас следует добавить в «Выбранные поля» именно группировки по Номенклатуре (в строках). Тогда они выведутся один раз в начале строки.Отклонение (ресурс) добавьте в общие «Выбранные поля» таблицы. СКД сама распределит его значения по пересечениям строк (товаров) и колонок (дат).Чтобы отчет выводил разницу (например, «+1» или «-2»), проанализируем использование Вычисляемых полей. Это позволит нам не перегружать запрос математической логикой.
Создадим поле Отклонение. В выражении напишем формулу, учитывающую оба порога. Посмотрим на пример выражения:
ВЫБОР
КОГДА ЕстьNull(Остаток, 0) > ЕстьNull(МаксимальныйЗапас, 999999)
ТОГДА Остаток - МаксимальныйЗапас
КОГДА ЕстьNull(Остаток, 0) < ЕстьNull(МинимальныйЗапас, 0)
ТОГДА Остаток - МинимальныйЗапас
ИНАЧЕ 0
КОНЕЦ
Важный момент: использование функции ЕстьNull обязательно. Если для товара не задан МаксимальныйЗапас, а мы попытаемся вычесть его из остатка, результатом будет NULL, и ячейка в отчете останется пустой.
Чтобы отчет выглядел профессионально, как в примере автора (с префиксами «+» и «-»), воспользуемся вкладкой «Условное оформление»:
Отклонение.Отклонение Больше 0.+. Также можно задать цвет текста (например, синий).Отклонение Меньше 0. Здесь можно задать красный цвет текста.Отклонение Равно 0. В оформлении выберите «Текст» и оставьте его пустым, чтобы не загромождать отчет нулями там, где остатки в норме.Не забудьте настроить вкладку «Ресурсы». Для полей Остаток, МинимальныйЗапас и МаксимальныйЗапас обычно используется функция СУММА(ИмяПоля) или МАКСИМУМ(ИмяПоля). Если вы используете «СрезПоследних», то для ресурсов МинЗапас и МаксЗапас лучше использовать МАКСИМУМ, чтобы при группировке по складу значения не суммировались некорректно.
Проанализировав ситуацию с «размножением» строк, мы видим, что правильное распределение полей между строками таблицы и выбранными полями группировок полностью решает проблему. Теперь данные по «Товару 1» будут занимать ровно одну строку, а все отклонения по дням выстроятся в аккуратный ряд в соответствующих колонках дат.