Почему не срабатывают необязательные параметры в СКД и как их правильно устанавливать программно?

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

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

Суть проблемы: необязательные параметры и виртуальные таблицы

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

Пример проблемного запроса:


ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
    ПродажиОбороты.Номенклатура,
    ПродажиОбороты.Регистратор,
    ПродажиОбороты.КоличествоОборот,
    ПродажиОбороты.СтоимостьОборот,
    ПродажиОбороты.Контрагент
ИЗ
    РегистрНакопления.Продажи.Обороты(
        &НачалоПериода, 
        &КонецПериода, 
        Регистратор, 
        НЕ Номенклатура.Услуга 
        {Контрагент В ИЕРАРХИИ (&ОптоваяТорговля)} 
        {Контрагент.ОсновнойМенеджерПокупателя = &ОсновнойМенеджерПокупателя}
    ) КАК ПродажиОбороты

Проанализируем ситуацию: здесь параметры &ОптоваяТорговля и &ОсновнойМенеджерПокупателя заключены в фигурные скобки. Это означает, что СКД применит эти фильтры только в том случае, если они будут "включены" в компоновщике настроек. Если вы просто установите значение параметра, но не активируете флаг его использования, условие в итоговый SQL-запрос не попадет.

Программная установка параметров в ПриКомпоновкеРезультата

Для реализации логики прав доступа (например, когда рядовой менеджер видит только свои продажи, а администратор — всё), код обычно размещают в модуле объекта отчета в процедуре ПриКомпоновкеРезультата. Выясним, как выглядит правильная установка значений:


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

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

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

Однако даже такой код часто "не срабатывает". Проанализируем основные причины этой "мистики".

Причина 1: Приоритет пользовательских настроек

Это самая распространенная ловушка в СКД. В системе существует три уровня настроек:

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

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

Чтобы гарантированно изменить параметр, который доступен пользователю, мы должны найти его по идентификатору в пользовательских настройках:


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

Если ЗначениеПараметра <> Неопределено Тогда
    Идентификатор = ЗначениеПараметра.ИдентификаторПользовательскойНастройки;
    ЭлементПользовательскойНастройки = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(Идентификатор);
    
    Если ЭлементПользовательскойНастройки <> Неопределено Тогда
        ЭлементПользовательскойНастройки.Значение = ПараметрыСеанса.ТекущийПользователь;
        ЭлементПользовательскойНастройки.Использование = Истина;
    КонецЕсли;
КонецЕсли;

Причина 2: Свойство "Использование"

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

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

Причина 3: Кэширование и старые настройки

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

Если пользователь ранее открывал отчет, когда параметров еще не было или они были настроены иначе, старые настройки из хранилища могут перекрыть логику ПриКомпоновкеРезультата. Самый простой способ проверить это — нажать в отчете кнопку "Установить стандартные настройки". Это сбросит кэш и заставит систему применить актуальный программный код.

Рекомендации по проектированию условий в СКД

Разберем, как сделать ваши отчеты более надежными:

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

← На главную