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