Как правильно передать таблицу значений в ПостроительОтчета и избежать ошибки «Несоответствие типов»?

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

При разработке отчетов в системе «1С:Предприятие» программисты часто сталкиваются с необходимостью вывести данные, полученные не прямым запросом к базе данных, а сформированные программно в виде ТаблицыЗначений. Одним из наиболее быстрых инструментов для решения этой задачи является ПостроительОтчета. Однако при его использовании часто возникает ошибка: «Ошибка при вызове конструктора (ОписаниеИсточникаДанных): Несоответствие типов (параметр номер '1')». Рассмотрим подробно, почему это происходит и как правильно организовать передачу данных.

Причина ошибки: различие между Табличной Частью и Таблицей Значений

Разберем типичную ситуацию. Программист пытается передать данные из экранной формы в построитель, используя следующий код:

Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(Объект.тзТрансакции);

Выясним причину возникновения ошибки. В данном контексте Объект.тзТрансакции является объектом типа ТабличнаяЧасть. Несмотря на внешнее сходство с таблицей, с точки зрения платформы 1С — это разные типы объектов. Конструктор объекта ОписаниеИсточникаДанных жестко ограничен и принимает в качестве первого параметра только следующие типы:

Чтобы исправить ситуацию, нам необходимо преобразовать табличную часть в «чистую» таблицу значений. Проанализируем правильный вариант вызова:


// Используем метод Выгрузить(), чтобы получить объект типа ТаблицаЗначений
ТаблицаДляПостроителя = Объект.тзТрансакции.Выгрузить();
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТаблицаДляПостроителя);

Программное формирование отчета на основе Таблицы Значений

Теперь рассмотрим более сложный и практичный пример. Представим, что мы получили данные из внешнего источника (например, SQL-запросом) в объект ТаблицаЗначений и хотим вывести их пользователю с группировками, итогами и оформлением. Посмотрим на алгоритм реализации универсальной функции на стороне сервера.

Для корректной работы ПостроителяОтчета крайне важно соблюдать последовательность действий. Проанализируем шаги настройки:

  1. Подготовка источника: Убедимся, что все колонки в нашей ТаблицеЗначений имеют явно заданные типы данных. Если колонка будет иметь тип Произвольный, построитель может не понять, как по ней итожить данные.
  2. Инициализация построителя: Создаем объект и назначаем ИсточникДанных.
  3. Заполнение настроек: Это критически важный момент. Метод ЗаполнитьНастройки() должен вызываться сразу после установки источника, но до того, как мы начнем вручную менять состав группировок или ресурсов.
  4. Настройка колонок: Определяем, какие поля будут измерениями (группировками), а какие — ресурсами (итогами).

Рассмотрим пример реализации такой функции:


&НаСервере
Функция ПолучитьОтчетИзТЗ(ТЗ, ЗаголовокОтчета, СписокИзмерений, СписокРесурсов)
    
    Построитель = Новый ПостроительОтчета;
    Построитель.ТекстЗаголовка = ЗаголовокОтчета;
    
    // Передаем ТЗ в описание источника данных
    Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТЗ);
    
    // Сначала заполняем настройки по умолчанию на основании источника
    Построитель.ЗаполнитьНастройки();
    
    // Теперь настраиваем измерения (группировки строк)
    Для Каждого Элемент Из СписокИзмерений Цикл
        // Элемент.Ключ - это имя колонки в ТЗ
        Построитель.ИсточникДанных.Колонки[Элемент.Ключ].Измерение = Истина;
    КонецЦикла;
    
    // Настраиваем ресурсы (поля, по которым считаются итоги)
    Для Каждого Элемент Из СписокРесурсов Цикл
        // Указываем агрегатную функцию, например, СУММА
        Построитель.ИсточникДанных.Колонки[Элемент.Ключ].Итог = "СУММА(" + Элемент.Ключ + ")";
    КонецЦикла;
    
    // Настройка оформления
    Построитель.ЗаполнениеРасшифровки = ВидЗаполненияРасшифровкиПостроителяОтчета.ЗначенияГруппировок;
    Построитель.РазмещениеИзмеренийВСтроках = ТипРазмещенияИзмерений.Вместе;
    
    // Выполняем расчет и выводим в табличный документ
    Построитель.Выполнить();
    
    ТабДокумент = Новый ТабличныйДокумент;
    Построитель.Вывести(ТабДокумент);
    
    Возврат ТабДокумент;
    
КонецФункции

Тонкие моменты типизации колонок

Выясним еще одну причину, по которой ПостроительОтчета может вести себя некорректно. Если вы создаете ТаблицуЗначений программно, обязательно используйте объект ОписаниеТипов. Если построитель встретит колонку с неопределенным типом, он не сможет построить по ней итоги.

Рассмотрим пример правильного создания колонки:


МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Число"));
КЧ = Новый КвалификаторыЧисла(15, 2);
ОписаниеТипаЧисло = Новый ОписаниеТипов(МассивТипов, , , КЧ);

ТЗ.Колонки.Добавить("СуммаТранзакции", ОписаниеТипаЧисло);

Если данные приходят из SQL-запроса, проанализируем ситуацию наличия значений NULL. ПостроительОтчета не умеет складывать NULL с числами в итогах. Перед передачей таблицы в построитель рекомендуется пройтись по числовым колонкам и заменить все пустые значения на 0.

Особенности работы в управляемом приложении

Посмотрим на контекст выполнения кода. ПостроительОтчета — это объект, доставшийся нам в наследство от обычных форм (версии 8.0 и 8.1). В современном интерфейсе «Такси» и на управляемых формах работа с ним имеет свои ограничения:

Рекомендация: переход на СКД

Несмотря на удобство ПостроителяОтчета для простых задач, разберем, почему в современных конфигурациях лучше использовать Систему компоновки данных (СКД) с типом источника «Внешний набор данных»:

  1. Производительность: СКД эффективнее обрабатывает большие объемы данных в оперативной памяти.
  2. Гибкость: Пользователь сможет сам менять группировки, добавлять отборы и условное оформление без переписывания программного кода.
  3. Стабильность: СКД — это основной вектор развития платформы, и она лишена многих «глюков» старого построителя, связанных с кэшированием макетов или ошибками вложенных запросов.

Однако, если вам нужно быстро вывести временную таблицу "в два клика" без создания схем компоновки, использование метода Объект.ТабличнаяЧасть.Выгрузить() в связке с ПостроителемОтчета остается вполне рабочим и эффективным инструментом.

← На главную