Как исправить неверное суммирование тарифа и ошибку «деление на 0» в отчетах СКД?

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

При разработке отчетов в Системе компоновки данных (СКД), особенно в отраслевых решениях вроде 1С:ЖКХ, программисты часто сталкиваются с ситуацией, когда числовые показатели начинают вести себя непредсказуемо. Одной из самых распространенных проблем является «раздувание» тарифа: вместо того чтобы показать фиксированную ставку для услуги, отчет суммирует её по всем объектам (квартирам, лицевым счетам), выдавая астрономические цифры. Вторая по популярности проблема — критическая ошибка «Деление на 0» при попытке рассчитать производные показатели в ресурсах.

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

Причина №1: Некорректная агрегация в ресурсах

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

Рассмотрим, как это исправить:

  1. Перейдем на вкладку Ресурсы в схеме компоновки данных.
  2. Найдем поле Тариф.
  3. В колонке «Выражение» заменим Сумма(Тариф) на Максимум(Тариф) или Среднее(Тариф).
  4. Если тариф должен отображаться только в детальных записях (по конкретной услуге или лицевому счету), воспользуемся колонкой «Рассчитывать по...». Укажите там конкретную группировку (например, Услуга или ЛицевойСчет), и тогда в общих итогах по дому тариф не будет рассчитываться вовсе, что избавит от путаницы.

Причина №2: Дублирование записей при соединениях таблиц

Если вы заметили, что даже после настройки ресурсов значения тарифа или объемов увеличиваются кратно (например, ровно в 2 или 3 раза), проблему следует искать в тексте запроса. Разберем ситуацию: вы соединяете таблицу Начисления с таблицей Оплаты.

Посмотрим на пример логической ошибки в запросе:


ВЫБРАТЬ
    Начисления.ЛицевойСчет,
    Начисления.Тариф,
    Оплаты.СммаОплаты
ИЗ
    РегистрНакопления.Начисления КАК Начисления
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Взаиморасчеты КАК Оплаты
    ПО Начисления.ЛицевойСчет = Оплаты.ЛицевойСчет
    И Начисления.Услуга = Оплаты.Услуга

Если по одной услуге в одном месяце было два платежа, то строка начисления продублируется. СКД получит две строки с одинаковым тарифом, и итоговая сумма (ресурс) удвоится. Чтобы этого избежать, проанализируем архитектуру запроса. Рекомендуется сначала сгруппировать данные по оплатам во временной таблице, чтобы на одну связку «Лицевой счет + Услуга» приходилась ровно одна строка, и только потом выполнять ЛЕВОЕ СОЕДИНЕНИЕ.

Причина №3: Ошибка «Деление на 0» в вычисляемых полях

Когда мы пытаемся вычислить долю оплаты или произвести сложный расчет на основе тарифа, часто возникает ошибка «Division by zero». Это происходит потому, что в базе могут быть записи с нулевым тарифом или значением NULL.

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

Пример правильного выражения для поля СКД:


Выбор 
    Когда Тариф = 0 Тогда 0 
    Иначе Оплата * ДоляТарифа / Тариф 
Конец

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

Причина №4: Проблема исчезновения данных при отборах

Часто программисты пытаются решить проблему нулевых значений «в лоб», устанавливая в настройках отчета фильтр Тариф > 0. Рассмотрим, почему это плохая практика. Если вы используете ЛЕВОЕ СОЕДИНЕНИЕ к данным по оплате и ставите жесткий отбор по тарифу из основной таблицы, то при отсутствии тарифа (например, услуга была сторнирована или пересчитана) из отчета исчезнет вся строка целиком, включая данные об оплате и корректировках.

Вместо жестких отборов в настройках, проанализируем возможность обработки таких данных внутри запроса или через условное оформление. Если нужно скрыть нулевые строки, лучше использовать Условное оформление (вкладка «Настройки»), устанавливая свойство «Видимость = Ложь» для строк, где тариф равен нулю, но при этом не исключая их из общего расчета итогов.

Работа с подключаемыми макетами оформления

Пользователи часто отмечают, что отчет «ломается» именно в момент подключения собственного макета. Выясним причину этого явления. В СКД макет — это не просто «картинка», это жесткая привязка областей к группировкам. Если в макете вы указали параметр Тариф и привязали его к ячейке, СКД будет выводить в эту ячейку результат расчета ресурса.

Если вы хотите, чтобы в макете тариф не суммировался:

Итоги и рекомендации

Подведем итог нашему исследованию проблем СКД в ЖКХ. Чтобы ваш отчет всегда выводил корректные данные, придерживайтесь следующих правил:

  1. Тариф — это не сумма. Всегда используйте Максимум или Минимум в ресурсах для полей, которые не являются оборотными по своей сути.
  2. Группируйте данные до соединения. Не допускайте ситуации «один ко многим» при связи начислений и оплат, если не планируете использовать детальные записи.
  3. Всегда проверяйте делитель. Любая формула с делением должна быть обернута в оператор Выбор Когда ... Тогда.
  4. Используйте ЕстьNULL. В запросах 1С это лучший способ избежать пустых ячеек, которые «ломают» математические операции в компоновке.

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

← На главную