Почему возникает ошибка при установке ВидСравнения.Содержит в отборе построителя 1С и как её исправить

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

При программной настройке отборов в объектах ПостроительОтчета или ПостроительЗапроса разработчики нередко сталкиваются с исключением во время присвоения значения свойству ВидСравнения. Например, при попытке установить строковое условие поиска возникает ошибка о том, что для данного поля доступен только ограниченный набор видов сравнения.

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

Причина возникновения ошибки несовместимости вида сравнения

Проанализируем механику работы коллекции Отбор в построителях. Доступные элементы перечисления ВидСравнения для каждого конкретного поля отбора жестко определяются типом данных этого поля в исходном запросе или источнике данных:

  1. Строковые поля: для них поддерживаются операции контекстного поиска — ВидСравнения.Содержит, ВидСравнения.НеСодержит, ВидСравнения.НачинаетсяС.
  2. Ссылочные поля: для ссылок на объекты метаданных (справочники, документы, планы видов характеристик) доступны проверки на равенство (ВидСравнения.Равно, ВидСравнения.НеРавно), нахождение в списке (ВидСравнения.ВСписке, ВидСравнения.НеВСписке), иерархическое вхождение (ВидСравнения.ВИерархии, ВидСравнения.НеВИерархии) и проверка заполненности.

Если поле (например, Счет или Договор) имеет тип СправочникСсылка.ДоговорыКонтрагентов, платформа физически не может применить строковое сравнение Содержит непосредственно к ссылке (GUID). Попытка выполнить такой код приводит к ошибке времени выполнения.

Способ 1. Добавление строкового реквизита в запрос построителя

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


// В тексте запроса построителя указываем строковое поле:
// ВЫБРАТЬ
//     Таблица.Договор КАК Договор,
//     Таблица.Договор.Наименование КАК ДоговорНаименование
// ИЗ
//     ...

После этого программная установка отбора по подстроке отработает корректно, так как поле ДоговорНаименование имеет тип Строка:


сзОтбор = ПостроительПоставки.Отбор;
сзОтбор.Добавить("ДоговорНаименование");
сзОтбор["ДоговорНаименование"].Использование = Истина;
сзОтбор["ДоговорНаименование"].ВидСравнения = ВидСравнения.Содержит;
сзОтбор["ДоговорНаименование"].Значение = "Основной";

Способ 2. Предварительный поиск ссылок и отбор списком

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


// Получаем массив или список подходящих ссылок
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    Договоры.Ссылка КАК Ссылка
    |ИЗ
    |    Справочник.ДоговорыКонтрагентов КАК Договоры
    |ГДЕ
    |    Договоры.Наименование ПОДОБНО ""%"" + &ИскомаяСтрока + ""%""";
Запрос.УстановитьПараметр("ИскомаяСтрока", ИскомыйТекст);

СписокСсылок = Новый СписокЗначений;
СписокСсылок.ЗагрузитьЗначения(Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка"));

// Устанавливаем корректный вид сравнения для ссылочного поля
сзОтбор = ПостроительПоставки.Отбор;
сзОтбор.Добавить("Счет");
сзОтбор["Счет"].Использование = Истина;
сзОтбор["Счет"].ВидСравнения = ВидСравнения.ВСписке;
сзОтбор["Счет"].Значение = СписокСсылок;

Правильная очистка и сброс отборов в построителе

Обратим внимание на управление составом коллекции Отбор. У объекта Отбор в построителе нет штатного метода Очистить(), а удаление элементов в цикле по индексам усложняет код и может приводить к ошибкам.

Разберем два стандартных подхода для сброса условий:

  1. Отключение флага использования: наиболее быстрый и безопасный способ сбросить фильтрацию без разрушения структуры коллекции:
    
    Для Каждого ЭлементОтбора Из ПостроительПоставки.Отбор Цикл
        ЭлементОтбора.Использование = Ложь;
    КонецЦикла;
    
  2. Сброс настроек построителя к значениям по умолчанию: вызов метода ЗаполнитьНастройки() восстанавливает первоначальную структуру полей отбора из текста запроса: ПостроительПоставки.ЗаполнитьНастройки();

Применение этих правил позволяет избежать ошибок типов и обеспечивает стабильную работу динамических отборов в отчетах и обработках.

← На главную