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

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

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

В этой статье мы подробно разберем, как управлять доступными значениями параметров и отборов, проанализируем типичные ошибки при работе с КомпоновщикомНастроек и рассмотрим несколько эффективных способов решения задачи.

Понимание механизмов ограничения: ДоступныеЗначения vs ПараметрыВыбора

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

  1. ДоступныеЗначения (AvailableValues): Этот механизм жестко ограничивает ввод. Если вы заполняете этот список, поле ввода в пользовательском режиме превращается из поля с кнопкой выбора (открывающей справочник) в выпадающий список. Пользователь не сможет выбрать ничего, кроме того, что вы явно указали.
  2. ПараметрыВыбора (ChoiceParameters): Этот метод работает мягче. Он накладывает фильтр на стандартную форму выбора (например, форму списка справочника). Пользователь нажимает кнопку выбора, открывается форма справочника, но в ней он видит только отфильтрованные элементы.

Рассмотрим по шагам, как реализовать эти подходы программно.

Способ 1: Использование параметров редактирования (ПараметрыВыбора)

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

Проанализируем пример кода, который позволяет установить отбор для параметра по списку значений:


// Получаем схему из макета
СхемаКомпоновкиДанных = РеквизитФормыВЗначение("Объект").ПолучитьМакет("МояСхемаСКД");

// Ищем нужный параметр в схеме
МойПараметр = СхемаКомпоновкиДанных.Параметры.Найти("Склад");

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

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

Способ 2: Использование функции общего модуля (через Выражение)

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

Выполним следующие шаги:

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

Функция ПолучитьСписокРазрешенныхСкладов() Экспорт
    Список = Новый СписокЗначений;
    // Здесь ваша логика запроса к БД или получения настроек
    // Список.Добавить(...);
    Возврат Список;
КонецФункции

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

РаботаСОтчетами.ПолучитьСписокРазрешенныхСкладов()

Преимущество: Платформа берет на себя всю работу по обновлению интерфейса. Вам не нужно писать код в форме для переинициализации компоновщика.

Способ 3: Переинициализация КомпоновщикаНастроек (динамическое управление)

Если список значений должен меняться «на лету» в зависимости от того, что пользователь нажал на форме, нам придется программно модифицировать компоновщик. Основная проблема здесь — не потерять уже введенные пользователем настройки (даты, другие отборы). Чтобы упростить работу с объектами компоновки и сократить объем кода, можно использовать СКДБилдер, который выступает удобной оберткой над объектной моделью.

Разберем алгоритм правильной переинициализации:


// 1. Сохраняем текущие настройки пользователя, чтобы они не затерлись
ТекущиеНастройки = КомпоновщикНастроек.ПолучитьНастройки();

// 2. Помещаем модифицированную схему во временное хранилище
АдресСхемы = ПоместитьВоВременноеХранилище(МояИзмененнаяСхема, УникальныйИдентификатор);

// 3. Инициализируем источник доступных настроек
ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСхемы);

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

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

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

Типичные ошибки и нюансы

При реализации ограничения выбора программисты часто сталкиваются с тем, что код вроде бы верный, но список в интерфейсе остается полным. Рассмотрим причины:

Ограничение значений в пользовательских отборах

Если ваша задача — ограничить выбор не в параметрах, а в отборах (левая часть окна настроек), вам нужно работать с ДоступнымиПолямиОтбора. У каждого элемента ДоступноеПолеКомпоновкиДанных также есть свойство ПараметрыРедактирования, где можно программно установить ПараметрыВыбора по аналогии с первым способом. Если же вам нужно реализовать специфические виды сравнения, например, поиск по шаблону в списке, рекомендуем использовать расширение для отборов 'Подобно в списке'.

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

← На главную