К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как вызвать процедуру модуля менеджера в 1С

Как вызвать экспортную процедуру модуля менеджера в 1С: синтаксис обращения через Справочники.Имя, требования к экспорту, типовые ошибки и примеры кода на встроенном языке.

Модуль менеджера в 1С — это программный модуль прикладного объекта (справочника, документа, регистра и т.д.), в котором размещают серверные процедуры и функции, работающие с объектом в целом, а не с конкретной его ссылкой. Чтобы вызвать процедуру модуля менеджера, используется обращение через менеджер объекта: Справочники.Номенклатура.ИмяПроцедуры(), Документы.РеализацияТоваров.ИмяПроцедуры() и так далее. Вызов возможен только для процедур и функций, объявленных с ключевым словом Экспорт.

Типичная ситуация: разработчик поместил процедуру в модуль менеджера, а при вызове получает ошибку «Процедура или функция с указанным именем не определена». Причина почти всегда одна из трёх — процедура объявлена без Экспорт, обращение идёт не через менеджер, а через объект или ссылку, либо модуль менеджера недоступен в текущем контексте (например, вызов с клиента). Ниже разобраны синтаксис вызова, требования к объявлению процедур и способы диагностики ошибок.

Материал ориентирован на управляемые формы и режим тонкого клиента, но большая часть правил справедлива и для обычного приложения. Все примеры приведены на встроенном языке 1С.

Что такое модуль менеджера и когда процедуры размещают в нём

Модуль менеджера компилируется один раз на уровне менеджера объекта, а не для каждой ссылки. Поэтому в нём нет доступа к данным конкретного объекта через ЭтотОбъект — такой обращения там просто не существует. В модуль менеджера помещают логику, которая оперирует коллекцией объектов или создаёт новые: подбор данных для заполнения, печатные формы (процедура Печать), обработчики получения данных выбора, служебные операции над группой записей.

Типовые примеры размещения: функция получения цены по номенклатуре, процедура массового пересчёта итогов, формирование представления объекта. Если логика относится к одному конкретному объекту и ей нужны его реквизиты «напрямую», правильное место — модуль объекта, а не модуль менеджера.

Синтаксис вызова процедуры модуля менеджера

Обращение строится по шаблону: коллекция менеджеров → имя объекта конфигурации → имя экспортной процедуры. Для справочника это выглядит так:

// Вызов процедуры без параметров

Справочники.Номенклатура.ЗаполнитьСлужебныеДанные();

// Вызов функции с параметрами и получением результата

Цена = Справочники.Номенклатура.ПолучитьЦену(ТекущаяНоменклатура, ТекущаяДата);

Для документов, регистров и других типов меняется только имя коллекции:

Документы.РеализацияТоваровУслуг.СформироватьПечатнуюФорму(МассивСсылок);

РегистрыСведений.КурсыВалют.ОбновитьКурсыЗаПериод(НачалоПериода, КонецПериода);

ПланыОбмена.Полный.ВыполнитьРегистрациюИзменений(Узел);

Важно понимать разницу: Справочники.Номенклатура — это менеджер, а Ссылка.ПолучитьОбъект() — уже объект конкретного элемента. Экспортные процедуры модуля менеджера доступны только через менеджер; попытка вызвать их через ссылку или объект приведёт к ошибке.

bsl
// Объявление в модуле менеджера справочника
Процедура ЗаполнитьСлужебныеДанные() Экспорт
	// серверная логика
КонецПроцедуры

// Вызов из любого серверного контекста
Справочники.Номенклатура.ЗаполнитьСлужебныеДанные();

Требования к объявлению процедуры

Главное требование — ключевое слово Экспорт после списка параметров. Без него процедура считается локальной для модуля и снаружи недоступна, даже если имя указано верно. Это самая частая причина ошибки «Процедура или функция с указанным именем не определена».

// Доступна для вызова извне

Функция ПолучитьЦену(Номенклатура, Период) Экспорт

// ...

КонецФункции

// Недоступна: нет Экспорт

Функция РассчитатьСкидку(Сумма)

// ...

КонецФункции

Второе требование — контекст исполнения. Модуль менеджера исполняется только на сервере. Поэтому вызвать его процедуру напрямую из клиентской процедуры формы нельзя: нужен серверный вызов через процедуру с директивой &НаСервере или &НаСервереБезКонтекста. Для вызовов из форм чаще всего подходит &НаСервереБезКонтекста, потому что менеджеру не нужны данные формы.

Третий момент — параметры. При вызове через менеджер действуют обычные правила передачи параметров, но помните об ограничениях серверного вызова из формы: передавать можно только сериализуемые типы (примитивы, ссылки, структуры, массивы из допустимых типов). Передать, например, объект ТабличныйДокумент с клиента на сервер в параметрах нельзя.

Вызов из формы: пошаговая схема

Наиболее частый практический сценарий — вызов процедуры модуля менеджера по нажатию кнопки в форме. Порядок такой: клиентская процедура-обработчик вызывает серверную процедуру формы, а та уже обращается к менеджеру.

&НаКлиенте

Процедура ОбновитьДанные(Команда)

ОбновитьДанныеНаСервере();

КонецПроцедуры

&НаСервереБезКонтекста

Процедура ОбновитьДанныеНаСервере()

Справочники.Номенклатура.ЗаполнитьСлужебныеДанные();

КонецПроцедуры

Если серверной процедуре нужны реквизиты формы (например, выбранная ссылка), используйте &НаСервере и передавайте значения как параметры либо читайте их из реквизитов формы. Не передавайте сам объект формы — это невозможно и не нужно.

Порядок действий при вызове из формы
  1. 1
    Откройте модуль менеджера объекта и убедитесь, что процедура объявлена с Экспорт
  2. 2
    В модуле формы создайте серверную процедуру с директивой &НаСервереБезКонтекста
  3. 3
    Внутри неё вызовите процедуру через менеджер: Справочники.Имя.ИмяПроцедуры()
  4. 4
    Из клиентского обработчика вызовите серверную процедуру формы
  5. 5
    Проверьте работу в режиме предприятия и убедитесь в отсутствии ошибок контекста

Типовые ошибки и их диагностика

Ошибка «Процедура или функция с указанным именем не определена» возникает в трёх случаях: нет Экспорт, опечатка в имени, либо процедура находится не в модуле менеджера, а в модуле объекта. Модуль объекта и модуль менеджера — разные модули, и их экспортные методы не взаимозаменяемы: процедура модуля объекта вызывается через объект (Объект.ИмяПроцедуры()), а не через менеджер.

Ошибка вида «Метод объекта не обнаружен» при обращении через ссылку означает, что вызов построен неверно: ссылка не имеет методов менеджера. Проверьте, с чего начинается выражение — с Справочники.Имя (менеджер) или с переменной-ссылки.

Ошибка контекста при вызове с клиента сигнализирует о том, что серверный вызов организован неправильно: либо серверная процедура формы имеет директиву &НаКлиенте, либо вызов идёт из общего модуля без флага «Сервер». Проверьте флаги компиляции общего модуля: для вызова модуля менеджера нужен флаг «Сервер» (и, при необходимости, «Вызов сервера», если общий модуль вызывается с клиента).

Типичные ошибки
01
Процедура без Экспорт — вызов падает с ошибкой «не определена»
02
Обращение через ссылку или объект вместо менеджера — метод не обнаружен
03
Вызов напрямую из &НаКлиенте — ошибка недопустимого контекста
04
Размещение логики в модуле объекта вместо модуля менеджера и наоборот
05
Передача несериализуемых типов в параметрах серверного вызова

Альтернативы: общий модуль или модуль объекта

Модуль менеджера — не единственное место для серверной логики. Если процедура не привязана к конкретному типу объекта, её лучше разместить в общем модуле с флагами «Сервер» и «Вызов сервера»: такой код доступен отовсюду и не требует обращения через менеджер. Стандарт разработки фирмы «1С» рекомендует выносить в модуль менеджера только логику, логически принадлежащую объекту.

Если процедуре нужны данные конкретного объекта, используйте модуль объекта: вызов тогда идёт через Объект = Ссылка.ПолучитьОбъект(); Объект.ИмяПроцедуры();. Учтите, что ПолучитьОбъект() создаёт объект в памяти и читает данные из базы — это дороже, чем вызов метода менеджера, и не нужно, если логика не требует данных конкретной ссылки.

Где разместить процедуру

Модуль менеджера

Логика над типом объекта в целом: печать, подбор данных, массовые операции. Вызов через Справочники.Имя.Процедура().

Модуль объекта

Логика конкретной ссылки с доступом к её реквизитам через ЭтотОбъект. Требует ПолучитьОбъект().

Общий модуль

Универсальные алгоритмы без привязки к типу объекта. Нужны флаги Сервер и Вызов сервера.

Проверка результата и отладка

После внесения изменений обновите конфигурацию базы данных (F7 в конфигураторе) — без этого изменения модуля менеджера не попадут в исполняемый код. Затем проверьте вызов в режиме предприятия. Для отладки поставьте точку останова внутри процедуры модуля менеджера: отладчик останавливается в модулях менеджеров так же, как в любых серверных модулях, при условии включённой отладки на сервере.

Признак корректной работы — процедура выполняется без исключений, а её результат (возвращаемое значение, изменённые данные, сформированная печатная форма) соответствует ожиданию. Если вызов «молча» ничего не делает, проверьте, не перехвачено ли исключение конструкцией Попытка...Исключение выше по стеку, и временно добавьте запись в журнал регистрации через ЗаписьЖурналаРегистрации.

Контрольные точки

Как проверить результат

Компиляция модуля
Норма

Конфигуратор не выдаёт ошибок при проверке модуля

Тревожный признак

Сообщение о неопределённой процедуре или синтаксической ошибке

Вызов в режиме предприятия
Норма

Процедура выполняется, отладчик в ней останавливается

Тревожный признак

Исключение «Процедура не определена» или ошибка контекста

Результат работы
Норма

Возвращаемое значение и данные в базе соответствуют ожиданию

Тревожный признак

Вызов проходит, но данных нет — проверяйте транзакции и перехват исключений

Частые вопросы

Можно ли вызвать процедуру модуля менеджера с клиента напрямую?

Нет. Модуль менеджера исполняется только на сервере, поэтому из клиентской процедуры нужен промежуточный серверный вызов — процедура формы с директивой &НаСервере или &НаСервереБезКонтекста, либо экспортная процедура общего модуля с флагами «Сервер» и «Вызов сервера».

Почему возникает ошибка «Процедура или функция с указанным именем не определена»?

Чаще всего процедура объявлена без ключевого слова Экспорт, либо в имени опечатка, либо процедура находится в модуле объекта, а не в модуле менеджера. Откройте именно модуль менеджера (через контекстное меню объекта в дереве конфигурации) и проверьте объявление.

Чем вызов через менеджер отличается от вызова через объект?

Менеджер (Справочники.Имя) работает с типом в целом и не требует чтения данных из базы. Объект (Ссылка.ПолучитьОбъект()) загружает конкретную запись в память и даёт доступ к её реквизитам, но это дороже по ресурсам. Выбирайте по тому, нужны ли процедуре данные конкретной ссылки.

Доступны ли процедуры модуля менеджера в фоновом задании?

Да, фоновое задание исполняется на сервере, поэтому вызов через менеджер работает без ограничений. Это удобный способ вынести длительные операции (массовую обработку, пересчёты) из интерактивного сеанса.

Можно ли вызвать процедуру модуля менеджера другой конфигурации через расширение?

Из расширения можно вызывать экспортные процедуры модулей менеджеров основной конфигурации, если расширение работает в безопасном режиме с соответствующими разрешениями. Обратное — вызов процедур расширения из основной конфигурации — невозможен, так как основная конфигурация не знает о расширении.

Нужно ли обновлять конфигурацию базы данных после изменения модуля менеджера?

Да. Изменения любых модулей вступают в силу только после обновления конфигурации базы данных. Если вы изменили процедуру, но поведение не изменилось, первым делом проверьте, выполнено ли обновление и не работаете ли вы с кэшированной версией клиента.

Итог

Что важно запомнить

Вызов процедуры модуля менеджера строится через менеджер объекта: Справочники.Имя.Процедура(). Процедура должна быть экспортной, вызов возможен только на сервере, из формы — через серверную процедуру-прокладку. Большинство ошибок сводится к отсутствию Экспорт, неверному контексту или путанице между модулем объекта и модулем менеджера.