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