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

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

Работа с системой компоновки данных (СКД) в 1С требует четкого понимания того, как интерпретируются выражения в языке запросов и в языке выражений СКД. Часто разработчики сталкиваются с ситуацией, когда расчетное поле выводит пустые значения, «NULL» или логические ответы «Да/Нет» вместо ожидаемых чисел. В этой статье мы подробно разберем, почему возникают такие ошибки, и как правильно реализовать сложную логику расчета колонок с учетом категорий и свойств номенклатуры.

Анализ синтаксической ошибки в операторе ВЫБОР

Разберем типичную ситуацию, когда программист пытается вычислить значение в запросе, используя конструкцию ВЫБОР (CASE). Рассмотрим фрагмент кода, который часто становится причиной некорректной работы отчета:


ВЫБОР
    КОГДА ЗначенияСвойствОбъектов.Значение.Наименование = "Готовая продукция"
        ТОГДА _АналитическаяСправкаТовары.КоличествоПродажПлан = _АналитическаяСправкаТовары.КоличествоПродаж * _АналитическаяСправкаТовары.Ссылка.КоэффициентГотовая
    ...
КОНЕЦ

Проанализируем причину, по которой такой код не будет работать. В языке запросов 1С оператор ВЫБОР должен возвращать значение, которое будет помещено в результирующее поле. Однако внутри блока ТОГДА автор написал логическое выражение сравнения (Поле1 = Поле2 * Коэффициент). С точки зрения системы это выглядит как вопрос: «Равно ли Поле1 результату умножения?». Система честно отвечает на этот вопрос логическим типом: Истина или Ложь (что в интерфейсе отчета отображается как «Да» или «Нет»).

Для исправления ситуации нам необходимо убрать знак равенства и присваивание из блока ТОГДА. Рассмотрим правильный вариант написания условия:


ВЫБОР
    КОГДА ЗначенияСвойствОбъектов.Значение.Наименование = "Готовая продукция"
        ТОГДА _АналитическаяСправкаТовары.КоличествоПродаж * _АналитическаяСправкаТовары.Ссылка.КоэффициентГотовая
    КОГДА ЗначенияСвойствОбъектов.Значение.Наименование = "Сырая продукция"
        ТОГДА _АналитическаяСправкаТовары.КоличествоПродаж * _АналитическаяСправкаТовары.Ссылка.КоэффициентОбщий
    КОГДА ЗначенияСвойствОбъектов.Значение.Наименование = "Покупная мясопродукция"
        ТОГДА _АналитическаяСправкаТовары.КоличествоПродаж + 10
    ИНАЧЕ 0
КОНЕЦ

Проблема пустых строк и значений NULL

Выясним причину появления пустых строк в отчете. Если условие ВЫБОР не содержит блока ИНАЧЕ, и ни одно из условий КОГДА не выполнилось, система вернет значение NULL. В СКД NULL часто визуализируется как пустая ячейка.

Кроме того, если в расчете участвует хотя бы одно поле со значением NULL, результат всей математической операции также станет NULL. Например, если для товара не заполнен КоэффициентГотовая, то при умножении количества на этот пустой коэффициент мы получим пустоту. Чтобы этого избежать, всегда используем функцию ЕСТЬNULL. Посмотрим на примере:

ЕСТЬNULL(_АналитическаяСправкаТовары.КоличествоПродаж, 0) * ЕСТЬNULL(_АналитическаяСправкаТовары.Ссылка.КоэффициентГотовая, 1)

Учет иерархии категорий в условиях

Часто расчет должен зависеть не от конкретного значения свойства, а от его принадлежности к определенной группе (родительской категории). Если мы сравниваем наименование свойства напрямую (Значение.Наименование = "Готовая продукция"), а в объекте указана вложенная категория (например, «Колбасы», которая входит в «Готовую продукцию»), то условие не сработает.

Разберем по шагам, как решить проблему иерархии:

  1. Проверка родителя: В условии можно проверять не только само значение, но и его родителя: КОГДА ЗначенияСвойствОбъектов.Значение.Родитель.Наименование = "Готовая продукция".
  2. Использование оператора В ИЕРАРХИИ: Если уровней вложенности много, лучше использовать оператор В ИЕРАРХИИ. Однако в тексте запроса СКД его сложно использовать с жестко заданными строками. Рекомендуется выносить опорные категории в Параметры СКД.
  3. Создание дополнительных соединений: Мы можем в запросе левым соединением подтянуть таблицу справочника категорий, чтобы «поднять» данные о родителе верхнего уровня в основную выборку.

Типизация данных и производительность

Проанализируем важный аспект работы с регистром ЗначенияСвойствОбъектов. Поле Значение в этом регистре имеет составной тип. При обращении через точку к реквизитам такого поля (например, .Наименование или .Родитель), СУБД генерирует крайне неоптимальный SQL-запрос, пытаясь выполнить соединения со всеми возможными таблицами справочников.

Для оптимизации и корректного получения данных необходимо использовать функцию ВЫРАЗИТЬ. Рассмотрим, как это применить в нашем случае:


ВЫБОР
    КОГДА ВЫРАЗИТЬ(ЗначенияСвойствОбъектов.Значение КАК Справочник.КатегорииПродукции).Наименование = "Готовая продукция"
        ТОГДА ...
КОНЕЦ

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

Использование вычисляемых полей вместо запроса

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

Например, в поле «Выражение» для нового вычисляемого поля можно написать аналогичную конструкцию Выбор...Конец, используя при этом доступные в компоновке ресурсы и параметры. Это удобно, если коэффициенты (например, КоэффициентОбщий) должны выбираться динамически в зависимости от настроек пользователя.

Подведем итог:

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

← На главную