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

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

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

Суть проблемы: почему возникает ошибка пересечения

Разберем ситуацию: система компоновки данных имеет иерархическую структуру настроек. Фиксированные настройки обладают наивысшим приоритетом. Они накладываются поверх основных и пользовательских настроек по правилу логического «И». Ошибка «Невозможно применить фиксированные настройки. Пересекаются элементы отбора» чаще всего возникает, когда одно и то же поле (например, Склад или Подразделение) одновременно задействовано и в фиксированных, и в пользовательских настройках, доступных для интерактивного редактирования.

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

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

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

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


// В модуле команды или обработки, откуда открываем отчет
ПараметрыФормы = Новый Структура;

// Создаем объект фиксированных настроек
ФиксированныеНастройки = Новый НастройкиКомпоновкиДанных;
ЭлементОтбора = ФиксированныеНастройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));

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

// Устанавливаем режим отображения, чтобы пользователь не видел этот отбор
ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;

// Помещаем настройки в параметры под ключом ФиксированныеНастройки
ПараметрыФормы.Вставить("ФиксированныеНастройки", ФиксированныеНастройки);

// Открываем форму отчета
ОткрытьФорму("Отчет.МойОтчет.ФормаОбъекта", ПараметрыФормы);

Этот метод хорош тем, что фиксированные настройки применяются на самом раннем этапе жизненного цикла формы.

Способ 2. Использование события ПриСозданииНаСервере в форме отчета

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


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

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

Как программно избежать ошибки пересечения (Conflict Resolution)

Проанализируем ситуацию, когда мы добавляем фиксированный отбор, но он уже присутствует в пользовательских настройках (например, сохранен пользователем с прошлого запуска). Чтобы код действительно «убирал» ошибку, нам необходимо выполнить очистку конфликтующих элементов. Рассмотрим по шагам, как это реализовать:

  1. Определяем целевое поле: Находим поле, которое хотим сделать фиксированным.
  2. Обходим пользовательские настройки: Проверяем коллекцию КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.
  3. Удаляем или отключаем конфликт: Если находим элемент отбора по нашему полю, мы должны либо удалить его, либо установить Использование = Ложь.
  4. Устанавливаем фиксированную настройку: После очистки пересечений добавляем элемент в ФиксированныеНастройки.

Пример реализации функции очистки:


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

Методы Библиотеки стандартных подсистем (БСП)

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

Там мы можем установить флаг Настройки.События.ПередЗагрузкойНастроекВКомпоновщик = Истина. Затем в соответствующем обработчике ПередЗагрузкойНастроекВКомпоновщик мы задаем фиксированные настройки. Это гарантирует, что настройки будут применены в правильный момент времени, исключая визуальные «прыжки» параметров на форме.

Особенности работы с динамическими списками

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

Визуальные индикаторы применения настроек

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

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

← На главную