Почему не работает отбор в динамическом списке через ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора?

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

При разработке управляемых форм в 1С часто требуется программно наложить фильтр на динамический список при изменении реквизитов на форме. Для этого разработчики обычно обращаются к стандартной процедуре библиотеки стандартных подсистем (БСП) ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора. Однако при определенных условиях отбор перестает применяться или вызывает системное исключение «Несоответствие типов».

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

Причина 1. Смещение позиций параметров в вызове процедуры БСП

Выясним причину возникновения ошибки «Несоответствие типов». Посмотрим на типовую сигнатуру процедуры УстановитьЭлементОтбора в общем модуле ОбщегоНазначенияКлиентСервер:


Процедура УстановитьЭлементОтбора(ОбластьПоискаДобавления,
                                 знач ИмяПоля,
                                 знач ПравоеЗначение = Неопределено,
                                 знач ВидСравнения = Неопределено,
                                 знач Представление = Неопределено,
                                 знач Использование = Неопределено) Экспорт

Обратим внимание на порядок следования аргументов:

  1. ОбластьПоискаДобавления — коллекция элементов отбора компоновки данных.
  2. ИмяПоля — имя поля компоновки (строка или ПолеКомпоновкиДанных).
  3. ПравоеЗначение — значение для сравнения.
  4. ВидСравнения — значение перечисления ВидСравненияКомпоновкиДанных.
  5. Представление — пользовательское представление поля.
  6. Использование — флаг активности отбора типа Булево.

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

Способ 1. Корректная передача параметров в процедуру БСП

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


&НаКлиенте
Процедура ОтборПоГИПуПриИзменении(Элемент)

    ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора(
        Список.Отбор, 
        "ГИПы.ГИП", 
        ОтборПоГИПу, 
        ВидСравненияКомпоновкиДанных.Равно, 
        , 
        ЗначениеЗаполнено(ОтборПоГИПу)
    );

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

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


ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора(
    Список.Отбор, 
    "ГИПы.ГИП", 
    ОтборПоГИПу, 
    , 
    , 
    ЗначениеЗаполнено(ОтборПоГИПу)
);

Способ 2. Установка отбора в ФиксированныеНастройки динамического списка

Если пользовательский список часто перенастраивается или восстанавливает стандартные настройки, программный отбор в коллекции Список.Отбор может сбрасываться. Чтобы закрепить отбор жестко, установим его в ФиксированныеНастройки компоновщика:


&НаКлиенте
Процедура ОтборПоГИПуПриИзменении(Элемент)

    ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора(
        Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор,
        "ГИПы.ГИП",
        ОтборПоГИПу,
        ВидСравненияКомпоновкиДанных.Равно,
        ,
        ЗначениеЗаполнено(ОтборПоГИПу)
    );

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

Способ 3. Фильтрация по табличной части через параметры произвольного запроса

Когда поле отбора находится во вложенной табличной части объекта (например, табличная часть ГИПы документа или заказа), прямой отбор по полю "ГИПы.ГИП" в динамическом списке может обрабатываться СКД неоптимально или вовсе игнорироваться платформой в зависимости от сложности запроса.

Наиболее надежный и производительный вариант — использование параметров в тексте произвольного запроса динамического списка. Разберем по шагам, как это реализовать.

В тексте запроса динамического списка в секцию ГДЕ добавим условие с подзапросом:


ГДЕ 
    НЕ &ИспользоватьОтборПоГИП
    ИЛИ ДокументЗаказ.Ссылка В (
        ВЫБРАТЬ 
            ВложеннаяТЧ.Ссылка 
        ИЗ 
            Документ.Заказ.ГИПы КАК ВложеннаяТЧ 
        ГДЕ 
            ВложеннаяТЧ.ГИП = &ОтборПоГИПу
    )

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


&НаКлиенте
Процедура ОтборПоГИПуПриИзменении(Элемент)

    Список.Параметры.УстановитьЗначениеПараметра("ОтборПоГИПу", ОтборПоГИПу);
    Список.Параметры.УстановитьЗначениеПараметра("ИспользоватьОтборПоГИП", ЗначениеЗаполнено(ОтборПоГИПу));

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

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

Способ 4. Прямое управление элементами компоновки без использования БСП

Рассмотрим вариант, когда конфигурация не содержит библиотеки БСП или требуется прямое управление объектом ЭлементОтбораКомпоновкиДанных:


&НаКлиенте
Процедура ОтборПоГИПуПриИзменении(Элемент)

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

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

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

← На главную