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