Как программно изменить список полей для выбора группировки в расшифровке СКД

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

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

Метод 1: Использование события ОбработкаРасшифровки

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

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

Разберем по шагам, как это реализовать:

  1. Перехватываем событие в форме отчета.
  2. Создаем объект ОбработкаРасшифровкиКомпоновкиДанных.
  3. Используем метод ПоказатьВыборДействия, передавая в него свой список доступных полей или фильтруя стандартные.

Посмотрим на пример логики кода:


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

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

Метод 2: Программная модификация схемы компоновки (СКД)

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

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


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

Этот метод хорош тем, что он «чистый» с точки зрения интерфейса — пользователю даже не будут предлагаться недопустимые варианты.

Метод 3: Использование ИсточникаДоступныхНастроек

Разберем еще один важный объект — ИсточникДоступныхНастроекКомпоновкиДанных. Этот объект инициализируется на основании схемы или адреса во временном хранилище. Если вы используете программный вывод отчета, вы можете подменить источник для процессора компоновки.

Проанализируем ситуацию: список доступных полей в расшифровке напрямую зависит от того, что «видит» компоновщик в этом источнике. Если создать ИсточникДоступныхНастроекКомпоновкиДанных на базе модифицированной схемы (как в Методе 2), то расшифровка будет работать строго по вашим правилам.

Как получить итоговый текст запроса после применения расшифровки

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

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


// 1. Получаем текущие настройки из данных расшифровки
НастройкиДляЗапроса = ДанныеРасшифровки.Настройки;

// 2. Используем компоновщик макета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

// 3. Генерируем макет компоновки
// Передаем схему, текущие настройки и данные расшифровки
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиДляЗапроса, ДанныеРасшифровки);

// 4. Текст запроса теперь доступен в наборах данных макета
Для Каждого НаборДанных Из МакетКомпоновки.НаборыДанных Цикл
    Если ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Тогда
        ТекстИтоговогоЗапроса = НаборДанных.Запрос;
        // Здесь можно проанализировать ТекстИтоговогоЗапроса
    КонецЕсли;
КонецЦикла;

Важный момент: в итоговом тексте запроса параметры могут быть заменены на литералы или представлены в виде &П. Если вам нужны реальные значения параметров, их следует искать в коллекции МакетКомпоновки.ЗначенияПараметров.

Резюме

Мы проанализировали несколько подходов к управлению списком полей в расшифровке СКД.

  1. Для динамического изменения меню прямо в момент клика лучше всего подходит перехват события ОбработкаРасшифровки и ручное управление объектом ОбработкаРасшифровкиКомпоновкиДанных.
  2. Для глобального ограничения полей (например, по правам доступа) эффективнее всего программно устанавливать ОграничениеИспользованияВГруппировке в самой схеме компоновки.
  3. Для отладки и анализа используйте КомпоновщикМакетаКомпоновкиДанных, который позволяет вытащить «подкапотный» запрос системы после всех манипуляций пользователя с расшифровкой.

Используя эти методы, мы можем создавать профессиональные и удобные отчеты, которые ведут себя именно так, как ожидает пользователь, сохраняя при этом контроль над производительностью и безопасностью данных.

← На главную