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