При разработке отчетов и обработок часто возникает необходимость отобрать данные не по одному конкретному значению, а сразу по группе элементов справочника (например, по нескольким видам оплаты или статусам). Попытка передать склеенную строку в метод НайтиПоКоду приведет к ошибке, так как данный метод рассчитан исключительно на поиск одного точного кода. Рассмотрим подробнее, как правильно реализовать выборку по нескольким элементам и какие ошибки могут встретиться в коде.
Метод Справочники.<ИмяСправочника>.НайтиПоКоду() ищет в базе строго одну запись, код которой в точности совпадает со строковым параметром. Передача выражения вида "000000002 + 000000001" воспринимается платформой как попытка найти элемент с таким экзотическим кодом, что возвращает пустую ссылку.
Чтобы отфильтровать данные по нескольким значениям, необходимо выполнить два действия:
В вместо оператора равенства =.Проанализируем условие отбора в секции ГДЕ. Когда отбор строится по одиночному значению, используется оператор =:
ГДЕ
РеализацияТоваровУслуг.ВидОплаты = &ВидОплаты
Для работы с несколькими элементами заменим условие на проверку вхождения в список параметров с помощью оператора В:
ГДЕ
РеализацияТоваровУслуг.ВидОплаты В (&СписокВидовОплаты)
И РеализацияТоваровУслуг.Дата МЕЖДУ &НачПериода И &КонПериода
И РеализацияТоваровУслуг.Проведен = ИСТИНА
Теперь соберем коллекцию элементов, которые будут переданы в параметр запроса &СписокВидовОплаты. Для этого можно использовать Массив или СписокЗначений. Если выбран режим отбора по двум видам оплаты одновременно, наполняем коллекцию найденными ссылками:
МассивВидовОплаты = Новый Массив;
МассивВидовОплаты.Добавить(Справочники.ВидыОплатыТЧ.НайтиПоКоду("000000001"));
МассивВидовОплаты.Добавить(Справочники.ВидыОплатыТЧ.НайтиПоКоду("000000002"));
Запрос.УстановитьПараметр("СписокВидовОплаты", МассивВидовОплаты);
Если требуется отобрать только один вид оплаты, в массив помещается лишь один элемент — запрос с конструкцией В (&СписокВидовОплаты) корректно обработает коллекцию любого размера.
При реализации данного кода разработчики нередко сталкиваются с исключением:
{Обработка.ПроверкаОплаты.Форма.Отчет(119)}: Метод объекта не обнаружен (Добавить)
Выясним причину этой ошибки. В модулях форм переменные, имена которых совпадают с реквизитами формы, реквизитами основного объекта или элементами управления, обращаются напрямую к контексту формы. Если на форме уже есть реквизит с именем ВидОплаты (имеющий ссылочный тип), то попытка присвоить ему новый объект или вызвать метод без явного переопределения локальной переменной приводит к конфликту.
Чтобы избежать подобных коллизий, используем следующие правила:
Перем.МассивВидовОплаты, СписокВидов), что исключает совпадение с реквизитами документа или формы.Использование метода НайтиПоКоду в коде конфигурации несет определенные риски: метод чувствителен к длине строки, ведущим нулям и уникальности кодов при ручном редактировании. Разберем альтернативные архитектурные решения:
ЗНАЧЕНИЕ(Справочник.ВидыОплатыТЧ.ИмяЭлемента), либо передавать через метод ПредопределенноеЗначение().
ГДЕ
РеализацияТоваровУслуг.ВидОплаты.Код В (&МассивКодов)
Массив, так как он расходует меньше оперативной памяти и не хранит вспомогательные метаданные (пометки, представления, картинки).В (&СписокВидовОплаты) вернет Ложь, и в результат запроса не попадет ни одна запись.