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