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