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

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

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

Разбираем, как вызвать процедуру из модуля объекта в 1С: экспортные методы, обращение через ссылку, типичные ошибки, ограничения клиент-серверного контекста и примеры кода.

Модуль объекта в 1С хранит логику конкретного прикладного объекта: документа, справочника, плана счетов и других сущностей. Код в нём выполняется в контексте данных объекта, поэтому обращаться к таким процедурам извне нужно с пониманием того, как устроен контекст и где физически исполняется код.

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

Ниже разобраны рабочие способы вызова, синтаксис с примерами, ограничения платформы и типичные ошибки, которые приводят к сообщениям вида «Процедура или функция с указанным именем не определена» или «Метод объекта не обнаружен».

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

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

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

Важно понимать: модуль объекта исполняется на сервере. Даже если директива компиляции не указана, по умолчанию методы модуля объекта компилируются в серверном контексте. Это определяет, откуда их можно вызывать и какие типы данных передавать в параметрах.

Базовый способ: вызов через объект, полученный по ссылке

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

// В модуле объекта документа

Процедура ПересчитатьИтоги() Экспорт

СуммаДокумента = Товары.Итог("Сумма");

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

// Вызов из другого модуля (например, из общего модуля)

ДокументОбъект = ДокументСсылка.ПолучитьОбъект();

ДокументОбъект.ПересчитатьИтоги();

ДокументОбъект.Записать();

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

Если объект уже открыт в контексте (например, вы работаете в обработчике проведения или в модуле формы с реквизитом типа ДанныеФормыСтруктура), получать объект повторно не нужно. В модуле формы объект доступен через РеквизитФормыВЗначение("Объект").

bsl
ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
ДокументОбъект.ПересчитатьИтоги();
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);

Ключевое слово Экспорт: почему без него вызов не сработает

Процедуры и функции модуля объекта по умолчанию являются приватными — доступны только внутри этого модуля. Чтобы сделать метод видимым снаружи, после заголовка добавляют ключевое слово Экспорт.

Функция ПолучитьСуммуНДС() Экспорт

Возврат Товары.Итог("СуммаНДС");

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

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

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

Вызов из формы: клиентский и серверный контекст

Из модуля формы напрямую вызвать процедуру модуля объекта нельзя — форма работает в клиентском контексте (в тонком и веб-клиенте), а модуль объекта исполняется на сервере. Правильный путь — серверная процедура формы.

Типовая схема выглядит так:

&НаСервере

Процедура ПересчитатьНаСервере()

ОбъектДанных = РеквизитФормыВЗначение("Объект");

ОбъектДанных.ПересчитатьИтоги();

ЗначениеВРеквизитФормы(ОбъектДанных, "Объект");

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

&НаКлиенте

Процедура КомандаПересчитать(Команда)

ПересчитатьНаСервере();

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

Здесь РеквизитФормыВЗначение преобразует данные формы в прикладной объект, после чего доступны все его экспортные методы. Затем ЗначениеВРеквизитФормы возвращает изменённые данные обратно в форму, чтобы пользователь увидел результат без перезаписи объекта в базу.

Обратите внимание: вызов РеквизитФормыВЗначение — относительно «дорогая» операция, так как данные сериализуются между клиентом и сервером. Не используйте её в обработчиках, срабатывающих на каждое изменение строки табличной части, без крайней необходимости.

Порядок вызова из формы
  1. 1
    Создайте в модуле формы серверную процедуру с директивой &НаСервере
  2. 2
    Преобразуйте данные формы в объект: РеквизитФормыВЗначение("Объект")
  3. 3
    Вызовите экспортную процедуру модуля объекта с нужными параметрами
  4. 4
    Верните данные в форму через ЗначениеВРеквизитФормы
  5. 5
    Вызовите серверную процедуру из клиентского обработчика команды или события

Альтернативы: когда вызов модуля объекта не нужен

Не каждую задачу стоит решать вызовом метода объекта. Если логика не требует загрузки всего объекта в память, рассмотрите другие варианты — они часто быстрее и проще в сопровождении.

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

Где разместить вызываемый код

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

Когда логика работает с данными конкретного экземпляра. Требует ПолучитьОбъект(), исполняется на сервере.

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

Когда нужна операция над типом объектов: создание, поиск, печать. Вызывается без загрузки объекта.

Общий модуль

Когда логика универсальна и не зависит от конкретного объекта. Может быть серверным, клиентским или с вызовом сервера.

Модуль формы

Только для логики интерфейса и взаимодействия с пользователем. Прикладную логику здесь размещать не следует.

Правило выбора простое: если методу нужны реквизиты и табличные части конкретного объекта — это модуль объекта. Если методу достаточно ссылки или параметров — модуль менеджера или общий модуль будут лучшим выбором.

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

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

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

Третья группа — логические ошибки: процедура вызвана, результат посчитан, но не сохранён, потому что забыт метод Записать(). Либо наоборот: объект записан в середине обработки, что привело к проведению документа раньше времени и сработке подписок на события.

Типичные ошибки
01
Вызов метода у ссылки вместо объекта: у Ссылка.ИмяМетода() методов модуля объекта нет, нужен Ссылка.ПолучитьОбъект().ИмяМетода()
02
Отсутствие ключевого слова Экспорт — платформа сообщает, что процедура не определена
03
Попытка вызвать серверный метод объекта из клиентской процедуры формы без серверной обёртки
04
Вызов процедуры без последующего Записать() — изменения теряются
05
Использование ПолучитьОбъект() в цикле по большой выборке — деградация производительности
Контрольные точки

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

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

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

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

Сообщение «Процедура или функция не определена»

Выполнение вызова
Норма

Процедура отрабатывает, изменения видны в объекте или форме

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

Ошибка «Метод объекта не обнаружен»

Сохранение данных
Норма

После Записать() изменения присутствуют в базе при повторном открытии

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

Данные на месте только до закрытия формы

Контекст исполнения
Норма

Вызов работает и в толстом, и в тонком клиенте

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

В тонком клиенте ошибка контекста

Практические рекомендации по оформлению кода

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

Если метод объекта вызывается извне часто и с большими параметрами, проверьте, не передаются ли в параметрах значения, которые объект может получить сам из своих реквизитов. Лишние параметры усложняют сопровождение и повышают риск рассинхронизации данных.

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

Итог

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

Вызов процедуры из модуля объекта строится по схеме: получить объект по ссылке, вызвать экспортный метод, при необходимости записать результат. Процедура должна быть объявлена с Экспорт, исполняться в серверном контексте, а из формы вызываться через серверную обёртку с РеквизитФормыВЗначение.

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

Можно ли вызвать процедуру модуля объекта по имени объекта, как общий модуль?

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

Почему при вызове возникает ошибка «Метод объекта не обнаружен»?

Чаще всего причины три: у процедуры нет ключевого слова Экспорт, вызов выполняется у ссылки вместо объекта, либо в имени метода опечатка. Проверьте эти три пункта в указанном порядке.

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

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

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

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

Нужно ли записывать объект после вызова процедуры?

Только если процедура изменила данные, которые должны сохраниться в базе. Если метод выполняет вычисление и возвращает значение (функция), запись не нужна. Если изменены реквизиты или табличные части и результат должен сохраниться — вызовите Записать() с подходящим режимом.

Работает ли вызов из модуля команды?

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