Как настроить отборы в СКД для внешних отчетов при использовании объектов из расширений

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

Работа с внешними отчетами на базе Системы компоновки данных (СКД) в контексте использования расширений конфигурации часто сопряжена с рядом трудностей. Основные проблемы проявляются в невозможности редактирования схемы в конфигураторе из-за «ошибок получения информации набора данных» и «слетании» настроенных отборов по перечислениям при переносе отчета между базами. Рассмотрим детально, почему это происходит и какими способами можно обойти данные ограничения платформы.

Анализ проблемы: почему слетают отборы и возникают ошибки

Разберем первопричину. Когда мы создаем внешний отчет (файл .erf), схема компоновки данных сохраняет информацию об объектах метаданных. Если эти объекты (например, перечисления или новые реквизиты) добавлены через расширение, внешний отчет оказывается в «информационном вакууме». При открытии файла в Конфигураторе основная конфигурация «не знает» о типах данных из расширения, что приводит к невозможности корректно проанализировать запрос.

Ситуация с «пустыми значениями» в отборах по перечислениям в режиме Предприятия связана с особенностями сериализации. Платформа записывает значения отборов, используя внутренние идентификаторы. Если соответствие типов между расширением и внешним отчетом нарушается, ссылки превращаются в пустые значения. Также остро стоит вопрос обращения к составным полям, таким как Регистратор. Попытка получить Регистратор.Дата через точку заставляет СКД анализировать все таблицы документов, входящих в состав типа, и если часть из них находится в расширении, парсер запросов выдает ошибку.

Решение 1: Редактирование схемы через «контекстный хак» в расширении

Проанализируем самый эффективный способ правки схемы, когда Конфигуратор отказывается открывать конструктор запроса. Чтобы система «увидела» типы из расширения, нам нужно временно поместить процесс редактирования в контекст этого расширения. Выполним следующие шаги:

  1. Откроем основную конфигурацию и целевое расширение.
  2. В расширении создадим временный объект — например, Макет с типом «Схема компоновки данных».
  3. Скопируем содержимое (XML-текст) схемы из нашего внешнего отчета в этот макет.
  4. Откроем конструктор схемы в макете расширения. Теперь все объекты расширения доступны для выбора, и ошибки набора данных не возникнут.
  5. После внесения правок скопируем XML-код схемы обратно во внешний отчет.

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

Решение 2: Использование параметров СКД вместо фиксированных отборов

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

  1. В схеме на закладке «Параметры» создадим новый параметр, например, СостояниеСотрудника.
  2. Укажем нужный тип данных (соответствующее перечисление из расширения).
  3. В поле «Выражение» пропишем путь к конкретному значению: Перечисления.СостоянияСотрудника.Работает.
  4. В настройках отбора свяжем поле компоновки с этим параметром.

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

Решение 3: Оптимизация запроса и отключение автозаполнения

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

Механизм автозаполнения пытается автоматически определить все доступные поля и их связи. В случае с Регистратором это приводит к гигантским вложенным запросам ко всем таблицам документов. Чтобы этого избежать, выполним следующие рекомендации:

  1. В наборе данных «Запрос» снимем флаг «Автозаполнение».
  2. Вручную опишем все необходимые поля на закладке «Поля».
  3. Для полей составного типа, если типов слишком много, будем использовать явное приведение типов через ВЫРАЗИТЬ только для ключевых объектов.

Если регистраторов действительно много (десятки или сотни), и ВЫРАЗИТЬ делает запрос нечитаемым, применим методику временных таблиц. Сначала выберем данные во временную таблицу, подготовив все нужные реквизиты (включая даты и номера) простым запросом, а затем передадим эту таблицу в основной набор данных СКД.

Пример использования ВЫРАЗИТЬ в запросе:


ВЫБРАТЬ
    Продажи.Номенклатура,
    ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.РеализацияТоваровУслуг).Дата КАК ДатаРеализации
ИЗ
    РегистрНакопления.Продажи КАК Продажи
ГДЕ
    Продажи.Период МЕЖДУ &НачалоПериода И &КонецПериода

Решение 4: Программная установка отборов в событии ПриКомпоновкеРезультата

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

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


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

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

Решение 5: Использование механизма Характеристик

Выясним, как еще можно упростить доступ к полям расширения. В СКД существует механизм Характеристик. Мы можем описать дополнительные поля (из расширения) как характеристики для объектов основной конфигурации. Это позволит пользователю выбирать эти поля в настройках, а системе — корректно строить запросы для их получения, не перегружая основной текст запроса и избегая ошибок разыменования составных типов.

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

← На главную