При разработке конфигураций и доработке типовых решений начинающие разработчики часто сталкиваются с ситуацией, когда обращение к экспортной функции через менеджер объекта метаданных вызывает ошибку: «Метод объекта не обнаружен» или «Функция не найдена». Разберем детально, почему это происходит, в чем принципиальная разница между модулем объекта и модулем менеджера, а также рассмотрим корректные способы вызова логики.
Рассмотрим типовую ошибку. В модуле объекта документа ЗаказКлиента объявлена функция:
Функция Рассчитать() Экспорт
// Алгоритм расчета документа
Возврат Истина;
КонецФункции
Попытка вызвать ее напрямую через менеджер коллекции:
Документы.ЗаказКлиента.Рассчитать();
приводит к ошибке выполнения. Проанализируем причину: конструкция Документы.ЗаказКлиента обращается к объекту ДокументМенеджер, а не к конкретному экземпляру документа. Модуль менеджера предназначен для общих («статических») процедур и функций, относящихся ко всему объекту метаданных в целом (например, выборка данных, формирование печатных форм списков). Модуль объекта описывает логику и состояние только одного конкретного экземпляра документа, загруженного в оперативную память.
Если для выполнения расчета требуется инициализировать новый документ, создадим экземпляр объекта через менеджер и вызовем его экспортный метод:
ДокОбъект = Документы.ЗаказКлиента.СоздатьДокумент();
ДокОбъект.Рассчитать();
В данном случае переменная ДокОбъект содержит тип ДокументОбъект.ЗаказКлиента, в контексте которого доступна экспортная функция Рассчитать().
Если расчет должен выполняться для уже записанного в базу данных документа, получим его объект по имеющейся ссылке. Рассмотрим правильный и безопасный алгоритм получения объекта:
ПолучитьОбъект().Посмотрим на пример кода:
Если ЗначениеЗаполнено(СсылкаНаЗаказ) Тогда
ДокОбъект = СсылкаНаЗаказ.ПолучитьОбъект();
Если ДокОбъект <> Неопределено Тогда
Результат = ДокОбъект.Рассчитать();
КонецЕсли;
КонецЕсли;
Обратите внимание: метод Ссылка.ПолучитьОбъект() может вернуть Неопределено, если объект был удален из базы или у текущего пользователя ограничены права доступа (RLS). Всегда проверяйте результат на валидность.
Вызов метода ПолучитьОбъект() считывает из базы данных все реквизиты и табличные части, создавая тяжелый объект в памяти. Если функция Рассчитать() выполняет чисто математические вычисления и не меняет состояние конкретного документа, архитектурно правильнее вынести ее:
Экспорт прямо в модуле менеджера Документы.ЗаказКлиента. Входные данные передаем через параметры (например, структуру значений или массив). Тогда вызов Документы.ЗаказКлиента.Рассчитать(Параметры) отработает корректно и быстро.РасчетыСервер).Если объект получен правильно, но ошибка сохраняется, проверим следующие нюансы:
#Если Клиент Тогда или #Если Сервер Тогда, убедитесь, что контекст вызова соответствует директиве.