Как расширить список видов сравнения и программно установить отборы в компоновщике настроек на форме

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

При разработке произвольных отчетов или обработок на платформе 1С:Предприятие 8.3 часто используется объект КомпоновщикНастроекКомпоновкиДанных. Однако начинающие разработчики могут столкнуться с неприятной особенностью: при попытке настроить отбор на форме в колонке Вид сравнения доступен только вариант Равно. Это существенно ограничивает возможности пользователя, лишая его возможности использовать фильтры типа "В списке", "Содержит", "Больше" или "Меньше".

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

Причина ограничения видов сравнения до значения «Равно»

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

Рассмотрим основные факторы, влияющие на доступность видов сравнения:

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

Выясним причину на примере. Если в макете СКД нет текста запроса, а поля добавлены вручную в «Набор данных - объект», обязательно проверьте колонку Тип значения. Как только вы укажете там конкретный справочник или примитивный тип (Число, Дата), список видов сравнения расширится автоматически.

Способ 1: Расширение видов сравнения через создание набора данных

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

Рассмотрим шаги по правильной настройке макета:

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

Способ 2: Программная инициализация компоновщика настроек

Для того чтобы компоновщик на форме работал корректно, его нужно правильно инициализировать. Разберем пример кода в процедуре ПриСозданииНаСервере. Мы должны связать компоновщик с макетом и его источником настроек.


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

После такой инициализации, если в схеме (СКД) типы полей определены верно, компоновщик на форме предоставит все стандартные виды сравнения (в списке, не равно, заполнено и т.д.).

Программное добавление отборов при открытии формы

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

Рассмотрим алгоритм добавления элемента отбора:

  1. Обращаемся к настройкам компоновщика.
  2. Добавляем новый элемент в коллекцию Отбор.Элементы.
  3. Устанавливаем ЛевоеЗначение — это поле, по которому фильтруем.
  4. Устанавливаем ВидСравнения.
  5. Устанавливаем ПравоеЗначение (если нужно предустановить значение).
  6. Важный момент: включаем использование отбора и выводим его в пользовательские настройки.

Посмотрим на пример кода, который добавляет отбор по полю «Склад»:


&НаСервере
Процедура ДобавитьОтборНаФорму(ИмяПоля, ЗначениеОтбора = Неопределено)
    
    // 1. Создаем новый элемент отбора
    НовыйЭлемент = КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    
    // 2. Указываем поле. Имя поля должно совпадать с именем в СКД
    НовыйЭлемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ИмяПоля);
    
    // 3. Устанавливаем вид сравнения (например, Равно или В списке)
    НовыйЭлемент.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    
    // 4. Настраиваем использование
    НовыйЭлемент.Использование = Истина;
    
    // 5. Если передано значение, устанавливаем его
    Если ЗначениеОтбора <> Неопределено Тогда
        НовыйЭлемент.ПравоеЗначение = ЗначениеОтбора;
    КонецЕсли;
    
    // 6. Чтобы отбор появился в "Пользовательских настройках" на форме:
    НовыйЭлемент.ИдентификаторПользовательскойНастройки = "ОтборПоПолю_" + ИмяПоля;
    
КонецПроцедуры

Почему важен ИдентификаторПользовательскойНастройки?

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

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

Совет: Если вы хотите, чтобы пользователь видел отбор, но не мог его удалить, вы можете управлять свойствами РежимОтображения элемента отбора, установив его в РежимОтображенияЭлементаНастройкиКомпоновкиДанных.БыстрыйДоступ.

Комплексный пример инициализации

Соберем все знания воедино и создадим процедуру, которая полностью подготавливает компоновщик к работе при открытии формы обработки.


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

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

Подведем итоги

Для корректной работы КомпоновщикНастроекКомпоновкиДанных необходимо соблюдать три условия:

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

← На главную