Как исправить ошибку «Параметр с указанным именем не найден» в динамическом списке 1С?

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

При разработке управляемых форм в среде «1С:Предприятие 8» программисты часто сталкиваются с ситуацией, когда при открытии формы возникает ошибка: «Ошибка при вызове метода контекста (УстановитьЗначениеПараметра): Параметр с указанным именем не найден». Данная проблема обычно связана с особенностями работы динамического списка, Системы компоновки данных (СКД) и механизмом передачи параметров в управляемых формах.

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

---

Причина 1. Путаница между параметрами управляемой формы и параметрами динамического списка

Часто начинающие разработчики совершают классическую архитектурную ошибку. Они открывают форму в конфигураторе, переходят на вкладку «Параметры» в редакторе формы, добавляют туда новый параметр (например, РасчСч) и считают, что теперь этот параметр можно передавать в динамический список.

Рассмотрим, почему это не так:

Попытка установить значение параметра динамического списка, который был объявлен только как параметр формы, неизбежно приведет к ошибке, так как динамический список ничего не знает о реквизитах и параметрах самой формы.

---

Причина 2. «Тихое» исключение параметров из-за использования фигурных скобок {} в запросе

Проанализируем текст запроса, который привел к ошибке в рассматриваемой ситуации:


ВЫБРАТЬ
    ДокументУП_ДокументДДС.Ссылка,
    ДокументУП_ДокументДДС.ПометкаУдаления,
    ДокументУП_ДокументДДС.МестонахождениеДенежныхСредств
ИЗ
    Документ.УП_ДокументДДС КАК ДокументУП_ДокументДДС
{ГДЕ
    (ДокументУП_ДокументДДС.ВидОперации <> &ВидОперации),
    (ВЫБОР
        КОГДА &РасчСч
            ТОГДА ТИПЗНАЧЕНИЯ(ДокументУП_ДокументДДС.МестонахождениеДенежныхСредств) = ТИП(Справочник.УП_РасчетныеСчета)
    КОНЕЦ) КАК Поле1}

Обратим внимание на конструкцию в фигурных скобках: {ГДЕ ...}. Фигурные скобки в запросах динамических списков представляют собой расширение языка запросов СКД. Всё, что находится внутри этих скобок, является необязательным отбором.

Выясним причину проблемы подробнее:

  1. Если в пользовательских или программных настройках динамического списка (в элементе «КомпоновщикНастроек») не установлен активный отбор по полю Поле1, то СКД считает данное условие неиспользуемым.
  2. При генерации финального SQL-запроса к базе данных СКД полностью выбрасывает всю эту секцию из текста запроса в целях оптимизации производительности.
  3. Поскольку секция выброшена, параметр &РасчСч становится невостребованным. СКД динамически удаляет его из коллекции доступных параметров динамического списка.
  4. При выполнении кода Список.Параметры.УстановитьЗначениеПараметра("РасчСч", Истина) платформа генерирует исключение, так как параметра с таким именем физически больше нет в активной схеме компоновки.

---

Как правильно и безопасно устанавливать параметры динамического списка

Существует несколько надежных способов обойти эту проблему. Проанализируем каждый из них.

Способ A. Использование безопасного поиска параметров (без вызова исключения)

Вместо жесткой установки значения параметра, которая валит систему в ошибку, мы можем предварительно проверить наличие параметра в коллекции с помощью метода Найти():


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

КонецПроцедуры

Способ Б. Использование стандартных функций БСП

Если в вашей конфигурации внедрена Библиотека стандартных подсистем (БСП), то наиболее лаконичным и правильным решением будет вызов готовой общей процедуры, которая безопасно обрабатывает инициализацию параметров:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    ОбщегоНазначенияКлиентСервер.УстановитьПараметрДинамическогоСписка(Список, "РасчСч", Истина);

КонецПроцедуры

Способ В. Принудительное включение параметра в СКД (Всегда)

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

  1. Откройте свойства динамического списка и перейдите в режим редактирования схемы компоновки данных (запроса).
  2. Перейдите на вкладку «Параметры».
  3. Найдите параметр РасчСч.
  4. Снимите для него флаг «Ограничение доступности».
  5. Установите свойство «Использование» в значение «Всегда».

---

Оптимизация работы с типами данных в запросе (Замена ТИПЗНАЧЕНИЯ на ССЫЛКА)

В сообщениях темы форума затрагивается вопрос проверки составного типа данных реквизита МестонахождениеДенежныхСредств (который может содержать кассы, расчетные счета или контрагентов). Исходный код автора содержал проверку через функцию приведения типов:

ТИПЗНАЧЕНИЯ(Документ.МестонахождениеДенежныхСредств) = ТИП(Справочник.УП_РасчетныеСчета)

Важно: Использование конструкции ТИПЗНАЧЕНИЯ(...) = ТИП(...) в запросах 1С является неоптимальным (bad practice). Это заставляет СУБД выполнять дополнительные операции приведения типов, что негативно сказывается на скорости работы динамического списка, особенно при больших объемах данных.

Рассмотрим, как правильно решить эту задачу с помощью оператора ССЫЛКА. Этот оператор работает на уровне СУБД значительно быстрее и делает код понятным:


// Проверка на то, что местонахождение является расчетным счетом:
ДокументУП_ДокументДДС.МестонахождениеДенежныхСредств ССЫЛКА Справочник.УП_РасчетныеСчета

// Проверка на то, что местонахождение НЕ является кассой:
НЕ ДокументУП_ДокументДДС.МестонахождениеДенежныхСредств ССЫЛКА Справочник.УП_Кассы

---

Решение сложной логической задачи: Исключение конкретной комбинации условий

Разберем логический вопрос автора (Сообщение 14): как правильно составить условие в запросе, чтобы из динамического списка исключались документы, у которых вид операции равен «Выплата сотрудникам» И одновременно местом хранения денег является «Касса»? При этом выплаты сотрудникам по «Расчетному счету» и все остальные операции должны остаться в списке.

В сообщении 14 предложена ошибочная логика:
ГДЕ (ВидОперации <> &ВидОперации И Местонахождение НЕ ССЫЛКА Справочник.УП_Кассы)

Почему эта логика неверна: Логическое «И» (AND) между двумя отрицаниями скроет из списка вообще все документы с операцией «Выплата сотрудникам» (даже банковские), а также все документы других операций, если они проведены по кассе. Это классическая логическая ловушка.

Правильное решение (Вариант 1)

Используем логическое отрицание всей нежелательной комбинации условий (условие «НЕ (А И Б)»):


{ГДЕ
    НЕ (ДокументУП_ДокументДДС.ВидОперации = &ВидОперации 
        И ДокументУП_ДокументДДС.МестонахождениеДенежныхСредств ССЫЛКА Справочник.УП_Кассы)
}

Правильное решение (Вариант 2)

Раскрываем скобки по правилам булевой алгебры (закон де Моргана). Условие звучит так: «показывать документы, у которых вид операции НЕ равен выплате сотрудникам, ИЛИ у которых место хранения денег НЕ является кассой»:


{ГДЕ
    (ДокументУП_ДокументДДС.ВидОперации <> &ВидОперации 
     ИЛИ НЕ ДокументУП_ДокументДДС.МестонахождениеДенежныхСредств ССЫЛКА Справочник.УП_Кассы)
}

Оба варианта логически эквивалентны и будут корректно работать в динамическом списке, исключая только целевую нежелательную комбинацию и сохраняя все остальные документы.

← На главную