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

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

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

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

Анализ проблемы: почему поле остается доступным в форме

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


ПолеНаименование = ОтчетОбъект.СхемаКомпоновкиДанных.НаборыДанных.НаборДанных1.Поля.Найти("Наименование");
ПолеНаименование.ОграничениеИспользования.Поле        = Истина;
ПолеНаименование.ОграничениеИспользования.Группировка = Истина;
ПолеНаименование.ОграничениеИспользования.Порядок     = Истина;
ПолеНаименование.ОграничениеИспользования.Условие     = Истина;

Однако при открытии формы отчета и переходе в режим редактирования настроек варианта («Изменить вариант») поле по-прежнему отображается в дереве доступных полей. Выясним причину такого поведения платформы 1С:

  1. Кэширование контекста схемы формой: В управляемых формах источник доступных настроек инициализируется схемой отчета при создании формы. Простое изменение объекта схемы через РеквизитФормыВЗначение и обратная запись через ЗначениеВРеквизитФормы не приводят к автоматическому обновлению контекста пользовательского интерфейса настроек.
  2. Место исполнения кода: Если настройки схемы применяются в момент формирования отчета (например, в событии ПриКомпоновкеРезультата), платформа успевает учесть ограничения только для вывода данных в табличный документ, но интерактивный интерфейс настройки варианта уже сформирован со старыми доступными полями.

Способ 1. Установка ограничений в модуле объекта отчета

Посмотрим на самое простое решение задачи, если схема компоновки инициализируется вместе с объектом отчета. Ограничения на использование полей можно применить непосредственно в теле модуля объекта (вне процедур) или в обработчиках инициализации объекта:


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

В этом случае при создании объекта отчета на сервере схема компоновки сразу модифицируется до того, как форма отчета построит свои элементы управления и дерево доступных полей.

Способ 2. Инициализация компоновщика через временное хранилище в форме

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


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

Способ 3. Полное программное удаление поля из набора данных

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


НаборДанных = Схема.НаборыДанных.НаборДанных1;
ПолеСКД = НаборДанных.Поля.Найти("Наименование");
Если ПолеСКД <> Неопределено Тогда
    НаборДанных.Поля.Удалить(ПолеСКД);
КонецЕсли;

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

Важные нюансы при программном скрытии полей

  1. Пользовательские настройки: Если у пользователя ранее был сохранен вариант отчета, где скрываемое поле уже присутствовало в группировках или выбранных полях, наложение ограничений не удалит его автоматически из уже сформированной структуры. Рекомендуется программно проверять коллекцию Отчет.КомпоновщикНастроек.Настройки.Выбор.Элементы и очищать отключенные поля.
  2. Связи и выражения: Убедимся, что на скрываемое поле не ссылаются вычисляемые поля, пользовательские поля выражений или параметры компоновки данных, иначе при выполнении отчета платформа вызовет синтаксическую ошибку компоновки.
← На главную