Как программно установить отбор в отчете с использованием компоновщика настроек

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

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

Понимание структуры компоновщика настроек

Прежде чем переходить к коду, проанализируем, почему возникают сложности. В объекте КомпоновщикНастроек есть две основные коллекции, с которыми мы работаем:

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

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

Способ 1. Установка отбора при открытии формы через параметры

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

Разберем алгоритм действий по шагам:


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

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

Способ 2. Использование события ПриКомпоновкеРезультата

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

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


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

КонецПроцедуры

Способ 3. Работа через ФиксированныеНастройки

Проанализируем ситуацию, когда отбор должен быть жестким, то есть пользователь не должен иметь возможности его отключить или изменить в шапке отчета. Для этого в платформе предусмотрено свойство ФиксированныеНастройки.

Рассмотрим, как это реализовать:

  1. Создаем временный объект КомпоновщикНастроекКомпоновкиДанных.
  2. Устанавливаем в его свойстве Настройки.Отбор нужные нам элементы.
  3. Передаем Компоновщик.Настройки в параметр формы ФиксированныеНастройки.

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

Полезные советы и предотвращение ошибок

Проанализируем несколько важных моментов, которые помогут избежать "пустых" отчетов или программных сбоев:

1. Избегайте дублей. Перед добавлением элемента в коллекцию Элементы.Добавить(), всегда проверяйте, не существует ли уже такой отбор. Если вы добавите два отбора по одному и тому же полю (например, "ЦФО = Склад1" и "ЦФО = Склад2"), СКД объединит их по условию И, и в результате отчет будет пустым.

2. Использование Библиотеки стандартных подсистем (БСП). Если ваша конфигурация основана на современных типовых решениях (ERP, УТ 11, БП 3.0), настоятельно рекомендуем использовать программный интерфейс БСП. Это сокращает код до одной строки:


// Пример использования БСП
ОтчетыКлиентСервер.УстановитьЭлементОтбора(КомпоновщикНастроек.Настройки, "ЦФО", ЗначениеЦФО, Истина, ВидСравненияКомпоновкиДанных.Равно);

Метод УстановитьЭлементОтбора самостоятельно проверит наличие существующего поля, создаст его при необходимости или обновит значение.

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

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

Мы рассмотрели основные способы программного управления отборами. Выбор конкретного метода зависит от того, должен ли пользователь видеть этот отбор и насколько глубоко в логику отчета нужно вмешаться. Использование ПараметровФормы является наиболее рекомендуемым способом для простых задач открытия отчетов из документов.

← На главную