Как перевести отчет с Построителя отчетов на управляемые формы в 1С?

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

При переходе со старых конфигураций 1С (на обычных формах) на современные платформы с управляемым приложением разработчики часто сталкиваются с необходимостью адаптации старых отчетов. Разберем ситуацию, когда в основе сложного отчета лежит устаревший объект ПостроительОтчета. На обычных формах платформа сама генерировала удобные табличные поля для отборов, группировок и сортировок. В управляемых формах (УФ) такой автоматики для Построителя нет, а сам объект доступен исключительно на стороне сервера. Проанализируем, как решить эту задачу максимально эффективно.

Почему не стоит использовать ДинамическийСписок?

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

  1. Структура хранения настроек динамического списка и Построителя отчета кардинально различается.
  2. Передача сложных отборов (особенно с группами условий "И/ИЛИ") из динамического списка в старый объект потребует написания огромного количества нестандартного кода.
  3. Динамический список не предоставляет удобного механизма для управления группировками колонок и строк, что критично для аналитических отчетов.

Оставим эту идею и перейдем к двум рабочим методам решения проблемы.

Способ 1: Полный перевод отчета на Систему Компоновки Данных (Рекомендуемый)

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

  1. Отсутствие необходимости вручную программировать интерфейс: настройки КомпоновщикНастроекКомпоновкиДанных легко выводятся на форму и обеспечивают пользователя всеми нужными инструментами (отборы, параметры, сортировки, группировки).
  2. Платформа 1С берет на себя всю рутину по формированию отчета, включая поддержку расшифровок, сохранение вариантов отчета и фоновое формирование.
  3. Исключаются "костыли" и устаревший код, который может перестать поддерживаться в будущих релизах платформы.

При этом не стоит пытаться выпиливать свои собственные отборы на форме помимо того, что предоставляет штатный механизм СКД. В 99% случаев ручное вмешательство в интерфейс отборов делает пользовательский опыт только хуже.

Способ 2: Гибридный метод (Интерфейс от СКД, логика от Построителя)

Проанализируем ситуацию, когда в отчете содержится колоссальный объем унаследованного кода, и переписать его под СКД физически нет времени. В этом случае мы применим гибридный подход: "поженим" современный интерфейс СКД со старой логикой расчета.

Разберем по шагам логику реализации этого метода:

  1. Создание "пустышки" СКД: Создадим в отчете основную схему компоновки данных. В ней опишем простенький запрос к основной таблице, чтобы получить структуру доступных полей. Эта структура нужна только для того, чтобы пользователь мог выбирать поля в отборах и группировках.
  2. Вывод настроек на форму: Выведем реквизит отчета КомпоновщикНастроекКомпоновкиДанных.ПользовательскиеНастройки на управляемую форму. Пользователь увидит привычный интерфейс СКД.
  3. Перехват события компоновки: В модуле объекта отчета переопределим процедуру ПриКомпоновкеРезультата. Установим параметр СтандартнаяОбработка = Ложь, чтобы СКД не пыталась сама выполнить свой фиктивный запрос.

Теперь рассмотрим самое главное — программную трансляцию настроек от СКД к Построителю. Напишем логику обработки данных на сервере:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // 1. Инициализируем наш старый построитель
    МойПостроитель = Новый ПостроительОтчета;
    МойПостроитель.Текст = ПолучитьТекстЗапросаОтчета(); 
    
    // 2. Получаем настройки, которые пользователь задал в СКД на форме
    НастройкиСКД = КомпоновщикНастроек.ПолучитьНастройки();
    
    // 3. Транслируем отборы из СКД в Построитель
    Для Каждого ЭлементОтбора Из НастройкиСКД.Отбор.Элементы Цикл
        
        Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") И ЭлементОтбора.Использование Тогда
            
            ИмяПоля = Строка(ЭлементОтбора.ЛевоеЗначение);
            
            // Добавляем отбор в построитель
            НовыйОтбор = МойПостроитель.Отбор.Добавить(ИмяПоля);
            НовыйОтбор.Использование = Истина;
            НовыйОтбор.ВидСравнения  = ТранслироватьВидСравненияСКДвПостроитель(ЭлементОтбора.ВидСравнения);
            НовыйОтбор.Значение      = ЭлементОтбора.ПравоеЗначение;
            
        КонецЕсли;
        
    КонецЦикла;
    
    // 4. Транслируем группировки (упрощенный пример для строк)
    Для Каждого ЭлементГруппировки Из НастройкиСКД.Структура Цикл
        
        Если ТипЗнч(ЭлементГруппировки) = Тип("ГруппировкаКомпоновкиДанных") И ЭлементГруппировки.Использование Тогда
            Для Каждого ПолеГруппировки Из ЭлементГруппировки.ПоляГруппировки.Элементы Цикл
                МойПостроитель.ИзмеренияСтроки.Добавить(Строка(ПолеГруппировки.Поле));
            КонецЦикла;
        КонецЕсли;
        
    КонецЦикла;
    
    // 5. Выполняем построитель и выводим результат
    МойПостроитель.Выполнить();
    МойПостроитель.Вывести(ДокументРезультат);
    
КонецПроцедуры

Важное примечание: Приведенный код концептуальный. В реальной задаче вам потребуется написать функцию ТранслироватьВидСравненияСКДвПостроитель для конвертации типов (например, ВидСравненияКомпоновкиДанных.Равно в ВидСравнения.Равно), а также рекурсивно обойти группировки СКД, так как они могут быть вложенными.

Особенности работы с текстом запроса в Построителе

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

Во-первых, снимите флаг Автозаполнение для наборов данных СКД, иначе система будет пытаться накладывать отборы хаотично, что приведет к ошибкам.

Во-вторых, в тексте запроса Построителя обязательно используйте конструкции расширения языка запросов в фигурных скобках. Проанализируем пример правильного запроса:


ВЫБРАТЬ
    ПродажиОбороты.Номенклатура КАК Номенклатура,
    ПродажиОбороты.Контрагент КАК Контрагент,
    ПродажиОбороты.КоличествоОборот КАК Количество,
    ПродажиОбороты.СуммаОборот КАК Сумма
ИЗ
    РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК ПродажиОбороты
{ГДЕ
    ПродажиОбороты.Номенклатура.*,
    ПродажиОбороты.Контрагент.*}

Конструкция {ГДЕ ...} указывает Построителю, куда именно подставлять условия из коллекции МойПостроитель.Отбор. Без этих виртуальных таблиц и фигурных скобок программно переданные отборы будут проигнорированы платформой.

Подведение итогов

Подведем итог нашей работы. Использование ПостроительОтчета в управляемом приложении — это всегда компромисс и работа с техническим долгом ("древней технологией"). Мы выяснили, что оптимальный путь получения красивого интерфейса — это использование КомпоновщикНастроекКомпоновкиДанных.

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

← На главную