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