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

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

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

Система компоновки данных предоставляет мощные инструменты для решения этой задачи прямо "на лету". Проанализируем несколько подходов, от простого декларативного до гибкого программного.

Решение 1: Программная установка доступных значений в настройках (рекомендуемый способ)

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

Порядок действий:

  1. Откройте модуль объекта вашего отчета.
  2. Создайте обработчик события ПриСозданииНаСервере. В этом обработчике у нас есть доступ к компоновщику настроек (КомпоновщикНастроек) до открытия формы.
  3. Получите текущие настройки отчета с помощью метода КомпоновщикНастроек.ПолучитьНастройки().
  4. Найдите в структуре настроек нужный элемент отбора. Обычно это отбор по полю Организация. Поскольку отбор может находиться внутри групп, для поиска лучше использовать рекурсивную функцию.
  5. Создайте новый СписокЗначений и заполните его ссылками на те две организации, которые должны быть доступны для выбора.
  6. Установите этот список в качестве правого значения для найденного элемента отбора. Важно также установить вид сравнения ВидСравненияКомпоновкиДанных.ВСписке и включить использование этого отбора (Использование = Истина).
  7. Загрузите измененные настройки обратно в компоновщик методом КомпоновщикНастроек.ЗагрузитьНастройки(Настройки).

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

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

Этот код следует разместить в модуле объекта отчета.


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    // Получаем текущие настройки отчета из компоновщика
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();

    // Находим нужный элемент отбора по системному имени поля "Организация"
    // Предполагается, что в запросе СКД поле называется "Организация"
    ЭлементОтбораОрганизация = НайтиЭлементОтбора(Настройки.Отбор, "Организация");

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

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

    // Загружаем измененные настройки обратно в компоновщик
    КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
    
КонецПроцедуры

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

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

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

Как это настраивается:

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

Преимущества: простота и наглядность. Не нужен код.

Недостатки: низкая гибкость. Список организаций жестко задан в конфигурации. Этот метод не подойдет, если список должен быть разным для разных пользователей или меняться со временем без изменения конфигурации.

Решение 3: Динамическая модификация самой схемы компоновки

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

Общий принцип:

  1. В одном из обработчиков событий отчета (например, ПриКомпоновкеРезультата) получите схему компоновки данных отчета.
  2. Программно найдите в схеме нужный набор данных и в нем — поле Организация.
  3. С помощью метода УстановитьДоступныеЗначения() для найденного поля установите список нужных организаций.

Этот способ гарантирует, что ограничение будет действовать на всех уровнях и для всех вариантов отчета, так как изменяется сама "инструкция" по построению данных. Однако для задачи ограничения выбора в пользовательском фильтре он может быть избыточным, а метод с модификацией настроек (Решение 1) — более простым и целевым.

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

← На главную