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

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

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

Почему система запрашивает тип значения?

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

  1. Составной тип данных: Если левое поле отбора имеет составной тип (например, ДокументСсылка, включающий несколько видов документов), платформа не может предугадать, по какому конкретно типу пользователь хочет сделать отбор.
  2. Сброс типа в «Неопределено»: Даже если поле имеет простой, одиночный тип (например, СправочникСсылка.Контрагенты), при полной очистке значения («крестиком») платформа сбрасывает тип правого значения в состояние Неопределено. При следующей попытке выбора значения система снова потребует указать тип.
  3. Использование вида сравнения «В списке»: Когда пользователь выбирает вид сравнения В списке, правое значение автоматически инициализируется объектом СписокЗначений. По умолчанию этот список может хранить любые типы данных. Из-за этого при добавлении каждого нового элемента в список система будет требовать выбрать его тип.

Ниже мы рассмотрим два основных метода решения этой проблемы: быструю настройку в конфигураторе без программирования и универсальный программный метод.

Метод 1. Настройка схемы в конфигураторе (без программирования)

Если состав отборов в вашем отчете предопределен заранее на этапе разработки, мы можем легко избавить пользователя от окна выбора типа штатными средствами схемы компоновки данных.

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

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

Благодаря этому при интерактивном выборе у пользователя сразу откроется форма выбора конкретного справочника или документа, минуя шаг с определением типа.

Метод 2. Универсальный программный способ

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

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

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


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

Важные детали интеграции программного кода

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

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

// Пример для обычных форм (в контексте формы отчета)
ТекущиеДанные = ЭлементыФормы.Отбор.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
    ДоступноеПоле = КомпоновщикНастроек.Настройки.ДоступныеПоляОтбора.НайтиПоле(ТекущиеДанные.ЛевоеЗначение);
    Если ДоступноеПоле <> Неопределено Тогда
        // Применяем приведение типов для правого значения
        ТекущиеДанные.ПравоеЗначение = ДоступноеПоле.ТипЗначения.ПривестиЗначение(Неопределено);
    КонецЕсли;
КонецЕсли;

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

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

← На главную