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

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

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

Метод 1. Использование функциональных опций (Архитектурно верный путь)

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

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

  1. Создадим константу (например, ИспользоватьНесколькоОрганизаций) с типом Булево.
  2. Создадим объект Функциональная опция, привяжем её к этой константе и в составе опции укажем справочник Организации или конкретные реквизиты.
  3. В самой Схеме компоновки данных перейдем на вкладку «Настройки», выберем нужный отбор или параметр и в его свойствах (внизу справа) найдем пункт Функциональные опции. Укажем там нашу созданную ФО.

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

Метод 2. Программное управление через Компоновщик настроек

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

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

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


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

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

Метод 3. Правильный выбор события формы

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

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


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

Почему нельзя просто скрыть элемент формы через «Видимость»?

Посмотрим на ситуацию со стороны пользователя. Если мы найдем элемент формы, отвечающий за отбор, и установим ему Элемент.Видимость = Ложь, мы получим потенциальную проблему — «магические фильтры».

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

Поэтому важно:

Метод 4. Обход элементов формы (для сложных случаев)

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


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    НастроитьЭлементыФормыНаСервере();
КонецПроцедуры

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

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

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

← На главную