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

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

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

Выясним причину появления пустых строк и пустых результатов сложения

В исходном запросе используется конструкция ОБЪЕДИНИТЬ ВСЕ для сбора данных из разных источников: документов заказов покупателей, заказов поставщикам, счетов на оплату и платежных документов (поступлений на счет и в кассу). В каждой отдельной ветке объединения поля, относящиеся к другим операциям, заполняются нулями либо значениями NULL.

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

Вторая проблема заключается в сложении колонок с помощью вычисляемых полей вида Сумма1 + Сумма2. Если хотя бы один из операндов содержит значение NULL, результат всей операции в языке выражений СКД (как и в языке запросов) также становится NULL. В отчете это отображается как пустая ячейка, несмотря на то, что в одном из слагаемых было реальное числовое значение.

Решение 1: Корректная обработка NULL в вычисляемых полях

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

В поле Выражение необходимо явно преобразовать потенциальные значения NULL в числовой ноль:

IsNull(СуммаПоступленияНаСчет, 0) + IsNull(СуммаПоступленияВКассу, 0)

Рассмотрим логику работы платформы в данном случае:

  1. Если операция содержит 63000 + NULL, стандартный механизм вычисления возвращает NULL (пустую ячейку).
  2. Конструкция IsNull(Сумма, 0) перехватывает отсутствие данных и подставляет 0. Выражение принимает вид 63000 + 0 = 63000, и итоговое число успешно отображается в отчете.

Решение 2: Разделение запроса на независимые наборы данных СКД

Попытка соединить все документы в одном огромном запросе через ОБЪЕДИНИТЬ ВСЕ или многочисленные ЛЕВОЕ СОЕДИНЕНИЕ часто приводит к каше из данных. Более чистый и поддерживаемый подход в СКД — разделить монолитный запрос на несколько логических наборов данных и настроить между ними связи.

Разберем по шагам, как перестроить отчет:

  1. Создаем набор данных №1 (Основной): выбираем документы верхнего уровня — например, Документ.ЗаказПокупателя с ключевыми реквизитами (ссылка, дата, контрагент, состояние заказа).
  2. Создаем набор данных №2 (Оплаты от покупателей): выбираем оплаты из документов поступления безналичных и наличных денежных средств с привязкой к заказу-основанию.
  3. Создаем набор данных №3 (Расчеты с поставщиками): выбираем заказы поставщикам, привязанные к заказу покупателя, и подчиненные им счета.
  4. Настраиваем связи: на вкладке Связи наборов данных связываем Набор №1 с Набором №2 и Набором №3 по полю Ссылка = ЗаказПокупателя.

Такой подход избавляет запрос от искусственных колонок с NULL и 0, а платформа компонует итоговое дерево группировок без лишних пустых строк.

Решение 3: Борьба с задвоением сумм при связях «один-ко-многим»

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

Рассмотрим подробнее два способа решения проблемы задвоения.

Способ А: Настройка вычисления ресурса с ограничением группировки

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

  1. В первой строке для поля СуммаСчетаНаОплату в поле Рассчитывать по... указываем группировку СчетНаОплату и пишем выражение: Максимум(СуммаСчетаНаОплату).
  2. Во второй строке для родительских группировок (например, по заказу покупателя) и для общих итогов настраиваем суммирование уникальных значений. Для этого используем функцию компоновки с массивом:
    
    Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СуммаСчетаНаОплату)", "СчетНаОплату"))
    

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

Способ Б: Предварительная агрегация во временных таблицах

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


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

После предварительной свертки соединение таблицы заказов с ВТ_ОплатыПоЗаказам будет гарантированно производиться с кратностью 1:1, что полностью устранит задвоение данных и исключит появление дублирующих пустых строк.

Рекомендации по структуре настроек отчета

В настройках структуры отчета на вкладке Настройки рекомендуется избегать прямого вывода разнородных по смыслу документов в общую кучу детальных записей. Разделите вывод на параллельные ветки группировок внутри заказа покупателя: отдельная дочерняя группировка по документам поступления денежных средств и отдельная ветка по документам расчетов с поставщиками. Для скрытия записей без движений достаточно добавить в отбор конкретной дочерней группировки условие СуммаЗаполнено = Истина.

← На главную