Универсальный отчет: как вывести текстовые данные в ячейки

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

При разработке и настройке отчетов в конфигурациях на обычных формах (например, «Управление торговлей 10.3», «Управление производственным предприятием 1.3» или «Бухгалтерия предприятия 2.0») разработчики часто используют стандартный механизм УниверсальныйОтчет. Однако при попытке вывести в качестве показателя (ресурса) текстовое значение — например, комментарий, статус или динамическое предупреждение — возникает ошибка формирования отчета.

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

Почему возникает ошибка при выводе строки в ресурс отчета

Разберем внутреннее устройство модуля УниверсальныйОтчет. Когда мы добавляем показатель через стандартный метод:


УниверсальныйОтчет.ДобавитьПолеРесурс("Предупреждение", """Работай дальше!""", "Предупреждение");
УниверсальныйОтчет.ДобавитьПоказатель("Предупреждение", "Текст предупреждения", Истина, , "Предупреждение");

Механизм отчета автоматически считает данное поле числовым ресурсом. При формировании итогового текста запроса построитель отчета (ПостроительОтчета) добавляет данное поле в секцию агрегирования итогов:


ИТОГИ
    СУММА(Предупреждение)
ПО
    ОБЩИЕ

В языке запросов 1С агрегатная функция СУММА() предназначена исключительно для числовых типов данных. Попытка передать в нее значение типа «Строка» вызывает синтаксическую ошибку компилятора запросов СУБД. Даже если правильно экранировать кавычки в коде 1С (используя тройные кавычки """Текст"""), запрос все равно упадет на этапе вычисления итогов.

Рассмотрим по шагам основные варианты обхода этого ограничения.

Способ 1. Использование дополнительных полей с привязкой к измерению

Если текст должен выводиться в строках отчета наряду с аналитикой (измерениями), его следует регистрировать не как показатель/ресурс, а как дополнительное поле. В этом случае механизм отчета не будет пытаться рассчитать по нему сумму.

Для этого выполним следующие действия:

  1. Вместо метода ДобавитьПолеРесурс зарегистрируем поле через ДобавитьДополнительноеПоле.
  2. Свяжем созданное поле с нужным измерением группировки с помощью метода УстановитьСвязьПоляИИзмерения.

Посмотрим на пример кода в модуле отчета:


// Регистрируем дополнительное поле, содержащее текстовое выражение или реквизит
УниверсальныйОтчет.ДобавитьДополнительноеПоле("Предупреждение", "ВЫБОР КОГДА ИсточникДанных.Оборот > 100 ТОГДА ""Работай дальше!"" ИНАЧЕ ""Норма"" КОНЕЦ", "Статус");

// Устанавливаем связь дополнительного поля с группировкой (измерением)
УниверсальныйОтчет.УстановитьСвязьПоляИИзмерения("Предупреждение", "Номенклатура");

При таком подходе текстовая колонка выводится рядом с указанным измерением (в данном примере — Номенклатура) и не попадает в агрегатную функцию СУММА() в блоке итогов.

Способ 2. Перевод источника данных на произвольный запрос

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

Проанализируем порядок действий при использовании источника типа «Запрос»:

  1. Устанавливаем тип источника данных "Запрос".
  2. Прописываем текст запроса вручную, определяя строковое поле в секции ВЫБРАТЬ.
  3. Если для строкового поля необходимо рассчитать итоги по группировкам, в секции ИТОГИ применяем функции МАКСИМУМ() или МИНИМУМ() вместо СУММА().

Разберем пример инициализации отчета через произвольный запрос:


// Задаем источник данных
УниверсальныйОтчет.УстановитьИмяИНачальныйМассивИнициализацииТекстаЗапроса("Запрос");

ТекстЗапроса = 
"ВЫБРАТЬ
|	ПродажиОбороты.Номенклатура КАК Номенклатура,
|	ПродажиОбороты.КоличествоОборот КАК Количество,
|	ВЫБОР
|		КОГДА ПродажиОбороты.КоличествоОборот > 100 ТОГДА ""Работай дальше!""
|		ИНАЧЕ ""Стандартный объем""
|	КОНЕЦ КАК ТекстПредупреждения
|{ВЫБРАТЬ
|	Номенклатура.*,
|	Количество,
|	ТекстПредупреждения}
|ИЗ
|	РегистрНакопления.Продажи.Обороты(&ДатаНач, &ДатаКон, Авто, ) КАК ПродажиОбороты
|{ГДЕ
|	ПродажиОбороты.Номенклатура.*}
|{ГРУППИРОВКА ПО
|	Номенклатура.*}
|ИТОГИ
|	СУММА(Количество),
|	МАКСИМУМ(ТекстПредупреждения)
|ПО
|	ОБЩИЕ,
|	Номенклатура";

УниверсальныйОтчет.ПостроительОтчета.Текст = ТекстЗапроса;

Функции МАКСИМУМ() и МИНИМУМ() корректно работают со строковыми типами в языке запросов 1С, благодаря чему построитель отчета успешно формирует итоговый документ без ошибок.

Способ 3. Использование Системы компоновки данных (СКД)

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

В СКД проблема вывода текстовых ячеек решена на уровне платформы:

← На главную