Почему возникает ошибка "Неверные параметры" при передаче списка счетов в запрос 1С с условием В ИЕРАРХИИ?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При разработке отчетов и обработок в платформе 1С:Предприятие разработчики часто сталкиваются с ситуацией, когда при выполнении запроса возникает ошибка компиляции вида «Неверные параметры» в секции фильтрации, например: И НЕ Счет В ИЕРАРХИИ (<<?>>&ИсключенныеСчета). Рассмотрим причины возникновения этой ошибки и разберем правильные способы передачи коллекций значений в параметры запроса.

Причина возникновения ошибки

Проанализируем ситуацию, когда исходный список счетов заполняется из обхода объекта СписокЗначений:


спСчетов = ОтчетыДляРуководителя.ПолучитьСписокСчетовИсключаемыхИзРасчетаЗадолженности(1);
Если спСчетов <> Неопределено Тогда
    Для Каждого Счет Из спСчетов Цикл
        Если Запрос.Параметры.ИсключенныеСчета.НайтиПоЗначению(Счет) = Неопределено Тогда
            Запрос.Параметры.ИсключенныеСчета.Добавить(Счет);
        КонецЕсли;
    КонецЦикла;
КонецЕсли;

При таком обходе конструкцией Для Каждого Счет Из спСчетов переменная Счет получает значение типа ЭлементСпискаЗначений, а не саму ссылку на счет (например, ПланСчетовСсылка.Хозрасчетный). Объект ЭлементСпискаЗначений содержит помимо самого значения служебные свойства: представление, пометку и картинку.

Операторы запроса В и В ИЕРАРХИИ предназначены для работы исключительно со ссылочными типами данных. Когда транслятор запросов 1С получает внутри списка параметров объект ЭлементСпискаЗначений, он не может сопоставить его с полем плана счетов в базе данных, что и вызывает сбой выполнения запроса.

Решение 1: Получение ссылки через свойство Значение

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


спСчетов = ОтчетыДляРуководителя.ПолучитьСписокСчетовИсключаемыхИзРасчетаЗадолженности(1);
Если спСчетов <> Неопределено Тогда
    Для Каждого Счет Из спСчетов Цикл
        // Обращаемся к ссылке через Счет.Значение
        Если Запрос.Параметры.ИсключенныеСчета.НайтиПоЗначению(Счет.Значение) = Неопределено Тогда
            Запрос.Параметры.ИсключенныеСчета.Добавить(Счет.Значение);
        КонецЕсли;
    КонецЦикла;
КонецЕсли;

В этом случае в коллекцию параметров попадает чистая ссылка на счет, и условие В ИЕРАРХИИ отрабатывает без ошибок.

Решение 2: Использование выгрузки значений и метода УстановитьПараметр()

Более правильным и эффективным стандартом разработки в 1С является отказ от ручного обхода элементов списка значений в цикле. Для получения массива ссылок из списка значений удобно использовать метод ВыгрузитьЗначения(), а установку параметра выполнять с помощью метода УстановитьПараметр().

Рассмотрим оптимальный вариант кода:


спСчетов = ОтчетыДляРуководителя.ПолучитьСписокСчетовИсключаемыхИзРасчетаЗадолженности(1);
Если спСчетов <> Неопределено Тогда
    // Получаем массив чистых ссылок из списка значений
    МассивСчетов = спСчетов.ВыгрузитьЗначения();
    
    // Передаем массив в параметр запроса
    Запрос.УстановитьПараметр("ИсключенныеСчета", МассивСчетов);
КонецЕсли;

Рекомендации по передаче параметров в запросы 1С

  1. Используйте Массив вместо СпискаЗначений: Объект Массив является универсальным, работает быстрее при передаче данных между клиентом и сервером и не содержит визуальных метаданных, в отличие от СписокЗначений.
  2. Применяйте метод УстановитьПараметр(): Прямое изменение свойства Запрос.Параметры является устаревшим подходом. Наглядное использование Запрос.УстановитьПараметр("ИмяПараметра", Значение) снижает риск ошибок.
  3. Проверяйте состав коллекции: Убедитесь, что в массив или список значений не попадают элементы типа Неопределено, NULL или строковые значения, если условие запроса рассчитано на ссылочные типы.
← На главную