При разработке управляемых форм в среде «1С:Предприятие 8» программисты часто сталкиваются с ситуацией, когда при открытии формы возникает ошибка: «Ошибка при вызове метода контекста (УстановитьЗначениеПараметра): Параметр с указанным именем не найден». Данная проблема обычно связана с особенностями работы динамического списка, Системы компоновки данных (СКД) и механизмом передачи параметров в управляемых формах.
В этой статье мы подробно разберем, почему возникает эта ошибка, в чем разница между параметрами формы и параметрами компоновщика данных, как фигурные скобки в запросах влияют на доступность параметров и как правильно оптимизировать логические условия в динамических списках.
---
Часто начинающие разработчики совершают классическую архитектурную ошибку. Они открывают форму в конфигураторе, переходят на вкладку «Параметры» в редакторе формы, добавляют туда новый параметр (например, РасчСч) и считают, что теперь этот параметр можно передавать в динамический список.
Рассмотрим, почему это не так:
Параметры.ИмяПараметра.Список.Параметры только тогда, когда они объявлены внутри самого текста запроса динамического списка (начинаются со знака амперсанда, например, &РасчСч) или добавлены во вкладке «Параметры» схемы компоновки данных самого динамического списка.Попытка установить значение параметра динамического списка, который был объявлен только как параметр формы, неизбежно приведет к ошибке, так как динамический список ничего не знает о реквизитах и параметрах самой формы.
---
Проанализируем текст запроса, который привел к ошибке в рассматриваемой ситуации:
ВЫБРАТЬ
ДокументУП_ДокументДДС.Ссылка,
ДокументУП_ДокументДДС.ПометкаУдаления,
ДокументУП_ДокументДДС.МестонахождениеДенежныхСредств
ИЗ
Документ.УП_ДокументДДС КАК ДокументУП_ДокументДДС
{ГДЕ
(ДокументУП_ДокументДДС.ВидОперации <> &ВидОперации),
(ВЫБОР
КОГДА &РасчСч
ТОГДА ТИПЗНАЧЕНИЯ(ДокументУП_ДокументДДС.МестонахождениеДенежныхСредств) = ТИП(Справочник.УП_РасчетныеСчета)
КОНЕЦ) КАК Поле1}
Обратим внимание на конструкцию в фигурных скобках: {ГДЕ ...}. Фигурные скобки в запросах динамических списков представляют собой расширение языка запросов СКД. Всё, что находится внутри этих скобок, является необязательным отбором.
Выясним причину проблемы подробнее:
Поле1, то СКД считает данное условие неиспользуемым.&РасчСч становится невостребованным. СКД динамически удаляет его из коллекции доступных параметров динамического списка.Список.Параметры.УстановитьЗначениеПараметра("РасчСч", Истина) платформа генерирует исключение, так как параметра с таким именем физически больше нет в активной схеме компоновки.---
Существует несколько надежных способов обойти эту проблему. Проанализируем каждый из них.
Вместо жесткой установки значения параметра, которая валит систему в ошибку, мы можем предварительно проверить наличие параметра в коллекции с помощью метода Найти():
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Ищем параметр в коллекции динамического списка
ПараметрРасчСч = Список.Параметры.Найти("РасчСч");
Если ПараметрРасчСч <> Неопределено Тогда
ПараметрРасчСч.Значение = Истина;
ПараметрРасчСч.Использование = Истина;
КонецЕсли;
КонецПроцедуры
Если в вашей конфигурации внедрена Библиотека стандартных подсистем (БСП), то наиболее лаконичным и правильным решением будет вызов готовой общей процедуры, которая безопасно обрабатывает инициализацию параметров:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ОбщегоНазначенияКлиентСервер.УстановитьПараметрДинамическогоСписка(Список, "РасчСч", Истина);
КонецПроцедуры
Если вам требуется, чтобы параметр всегда присутствовал в коллекции независимо от того, используется ли условие в фигурных скобках, выполните следующую настройку в конфигураторе:
РасчСч.---
В сообщениях темы форума затрагивается вопрос проверки составного типа данных реквизита МестонахождениеДенежныхСредств (который может содержать кассы, расчетные счета или контрагентов). Исходный код автора содержал проверку через функцию приведения типов:
ТИПЗНАЧЕНИЯ(Документ.МестонахождениеДенежныхСредств) = ТИП(Справочник.УП_РасчетныеСчета)
Важно: Использование конструкции ТИПЗНАЧЕНИЯ(...) = ТИП(...) в запросах 1С является неоптимальным (bad practice). Это заставляет СУБД выполнять дополнительные операции приведения типов, что негативно сказывается на скорости работы динамического списка, особенно при больших объемах данных.
Рассмотрим, как правильно решить эту задачу с помощью оператора ССЫЛКА. Этот оператор работает на уровне СУБД значительно быстрее и делает код понятным:
// Проверка на то, что местонахождение является расчетным счетом:
ДокументУП_ДокументДДС.МестонахождениеДенежныхСредств ССЫЛКА Справочник.УП_РасчетныеСчета
// Проверка на то, что местонахождение НЕ является кассой:
НЕ ДокументУП_ДокументДДС.МестонахождениеДенежныхСредств ССЫЛКА Справочник.УП_Кассы
---
Разберем логический вопрос автора (Сообщение 14): как правильно составить условие в запросе, чтобы из динамического списка исключались документы, у которых вид операции равен «Выплата сотрудникам» И одновременно местом хранения денег является «Касса»? При этом выплаты сотрудникам по «Расчетному счету» и все остальные операции должны остаться в списке.
В сообщении 14 предложена ошибочная логика:
ГДЕ (ВидОперации <> &ВидОперации И Местонахождение НЕ ССЫЛКА Справочник.УП_Кассы)
Почему эта логика неверна: Логическое «И» (AND) между двумя отрицаниями скроет из списка вообще все документы с операцией «Выплата сотрудникам» (даже банковские), а также все документы других операций, если они проведены по кассе. Это классическая логическая ловушка.
Используем логическое отрицание всей нежелательной комбинации условий (условие «НЕ (А И Б)»):
{ГДЕ
НЕ (ДокументУП_ДокументДДС.ВидОперации = &ВидОперации
И ДокументУП_ДокументДДС.МестонахождениеДенежныхСредств ССЫЛКА Справочник.УП_Кассы)
}
Раскрываем скобки по правилам булевой алгебры (закон де Моргана). Условие звучит так: «показывать документы, у которых вид операции НЕ равен выплате сотрудникам, ИЛИ у которых место хранения денег НЕ является кассой»:
{ГДЕ
(ДокументУП_ДокументДДС.ВидОперации <> &ВидОперации
ИЛИ НЕ ДокументУП_ДокументДДС.МестонахождениеДенежныхСредств ССЫЛКА Справочник.УП_Кассы)
}
Оба варианта логически эквивалентны и будут корректно работать в динамическом списке, исключая только целевую нежелательную комбинацию и сохраняя все остальные документы.