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