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

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

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

В этой статье мы подробно разберем, как правильно реализовать такое поведение системы, рассмотрим базовый способ настройки отборов на уровне группировок, а также решим критические проблемы производительности СУБД, особенности работы на обычных формах в УТ 10.3 и нюансы расчета общих итогов.

Базовый способ: перенос отбора из запроса в настройки группировки

Частой ошибкой начинающих разработчиков является жесткое указание параметра в секции ГДЕ основного запроса СКД. Например:


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

Если оставить запрос в таком виде, платформа принудительно потребует заполнения параметра &Менеджер для всего отчета. Применить его только к отдельной части структуры не получится. Чтобы решить эту задачу, выполним следующие шаги:

  1. Откроем конструктор схемы компоновки данных и перейдем на вкладку «Наборы данных».
  2. Удалим из секции ГДЕ условие фильтрации по менеджеру. Полностью очистим запрос от параметра &Менеджер. Проверим вкладку «Параметры» — автоматический параметр должен исчезнуть (или мы можем отключить его вручную).
  3. Перейдем на вкладку «Настройки». В структуре отчета выберем конкретную группировку (например, «Контрагент»), для которой необходимо установить фильтр.
  4. В окне настроек этой группировки (в нижней части экрана) перейдем на вкладку «Отбор».
  5. Добавим новый элемент отбора: левое значение — Контрагент.Менеджер, вид сравнения — Равно. Правое значение оставим доступным для выбора пользователем.
  6. Нажмем правой кнопкой мыши по созданному отбору и выберем пункт «Свойства элемента пользовательских настроек». Установим флаг «Включать в пользовательские настройки» и зададим понятное представление (например, «Менеджер для группировки»).

Теперь при формировании отчета СКД применит фильтр исключительно к выбранной ветке группировки, не затрагивая остальные таблицы.

Проблема 1: Оптимизация производительности (нагрузка на СУБД)

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

Если в базе данных хранятся сотни тысяч контрагентов, отчет мгновенно приведет к критическому падению производительности и ошибке нехватки памяти СУБД. Чтобы избежать этого, спроектируем отчет с использованием нескольких связанных наборов данных.

Выясним, как связать два набора данных для оптимизации:

  1. Создадим НаборДанных1 (запрос) — в нем выберем общие данные без отбора по менеджеру:
    
    ВЫБРАТЬ
        ВзаиморасчетыОстатки.Организация,
        ВзаиморасчетыОстатки.Контрагент,
        ВзаиморасчетыОстатки.СуммаВзаиморасчетовОстаток
    ИЗ
        РегистрНакопления.ВзаиморасчетыСКонтрагентами.Остатки КАК ВзаиморасчетыОстатки
    
  2. Создадим НаборДанных2 (запрос) — в нем выберем только тех контрагентов, которые соответствуют конкретному менеджеру:
    
    ВЫБРАТЬ
        Контрагенты.Ссылка КАК Контрагент,
        Контрагенты.ОсновнойМенеджерПокупателя КАК Менеджер
    ИЗ
        Справочник.Контрагенты КАК Контрагенты
    ГДЕ
        Контрагенты.ОсновнойМенеджерПокупателя = &Менеджер
    
  3. Перейдем на вкладку «Связи наборов данных». Добавим новую строку:
    • Источник связи: НаборДанных1
    • Приемник связи: НаборДанных2
    • Условие связи: Контрагент = Контрагент
    • Параметры: свяжем поле Менеджер с параметром &Менеджер

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

Проблема 2: Специфика обычных форм в УТ 10.3

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

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

  1. Добавим в СКД вспомогательный параметр с именем МенеджерНаФорме. Сделаем его доступным для изменения на форме.
  2. В модуле объекта отчета переопределим предопределенную процедуру ПриКомпоновкеРезультата.
  3. Пропишем программный перенос значения параметра в отбор конкретной группировки:

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

Этот код гарантирует, что пользователь сможет комфортно выбирать менеджера на обычной форме УТ 10.3, а система сама перенаправит этот выбор в настройки нужной группировки в обход глобального ограничения.

Проблема 3: Математика общих итогов отчета

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

Рассмотрим пример:

Если мы установим локальный отбор по Иванову для группировки «Контрагент», в строках отчета мы увидим детальные записи на сумму 150 000 руб., однако в строке «Итого» внизу отчета по-прежнему будет отображаться сумма 1 000 000 руб.

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

← На главную