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