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