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

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

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

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

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

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

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

Как устроен модуль объекта и почему прямой вызов невозможен

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

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

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

Объявление экспортной процедуры в модуле объекта

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

// Модуль объекта документа "РеализацияТоваров"

Процедура ПересчитатьИтоги(СУчетомСкидки = Ложь) Экспорт

// логика пересчёта табличной части

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

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

Параметры процедуры передаются как обычно. Учитывайте, что параметры-значения сложных типов (таблицы значений, структуры) при серверном вызове с клиента должны быть сериализуемыми, иначе вызов завершится ошибкой.

Вызов процедуры через ссылку: основной сценарий

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

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

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

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

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

Обратите внимание: изменения, которые процедура внесла в объект, не сохранятся в базу автоматически. Если результат должен быть зафиксирован, после вызова выполните Записать(). Если процедура нужна только для расчёта «на лету» (например, вернуть вычисленное значение через функцию), запись не требуется.

Порядок вызова процедуры модуля объекта
  1. 1
    Откройте модуль объекта и добавьте Экспорт к нужной процедуре
  2. 2
    В вызывающем коде получите объект: Объект = Ссылка.ПолучитьОбъект()
  3. 3
    Вызовите процедуру: Объект.ИмяПроцедуры(Параметры)
  4. 4
    Если данные изменились — выполните Объект.Записать()
  5. 5
    Проверьте результат отладчиком или по изменённым данным в базе

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

Вызов из модуля формы

В форме объекта (форма документа, форма элемента справочника) текущий объект доступен через реквизит формы Объект. На клиенте это данные формы, а не настоящий объект, поэтому прямой вызов процедуры модуля объекта возможен только на сервере после преобразования:

&НаСервере

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

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

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

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

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

Этот приём — преобразование реквизита формы в объект и обратно — стандартный способ выполнить серверную логику объекта из управляемой формы.

Вызов для нового, ещё не записанного объекта

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

НовыйДок = Документы.РеализацияТоваров.СоздатьДокумент();

НовыйДок.Дата = ТекущаяДатаСеанса();

НовыйДок.ПересчитатьИтоги();

НовыйДок.Записать();

Вызов из модуля другого объекта

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

bsl
// Универсальный шаблон вызова
ОбъектДляВызова = Ссылка.ПолучитьОбъект();
ОбъектДляВызова.ИмяЭкспортнойПроцедуры(Параметр1, Параметр2);
ОбъектДляВызова.Записать();

Когда лучше вынести логику в общий модуль

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

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

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

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

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

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

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

Операции над типом в целом без создания объекта: печать, заполнение, поиск.

Общий модуль

Универсальная логика, не зависящая от конкретного объекта. Вызывается напрямую по имени.

Типичные ошибки и ограничения

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

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

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

Типичные ошибки
01
Вызов процедуры через ссылку вместо объекта — ошибка «процедура не обнаружена»
02
Отсутствие Экспорт — процедура невидима извне модуля
03
Вызов ПолучитьОбъект() на клиенте — метод доступен только на сервере
04
Забытый Записать() после изменений — результат процедуры теряется
05
Использование ПолучитьОбъект() в массовом цикле — лишняя нагрузка на базу

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

Быстрый способ убедиться, что процедура отработала, — поставить точку останова внутри неё и запустить отладку. Если выполнение не дошло до точки, проверьте: объявлен ли Экспорт, тот ли объект вы получаете, не обрывается ли код раньше из-за исключения.

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

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

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

Точка останова внутри процедуры
Норма

Выполнение останавливается в процедуре

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

Точка не срабатывает — проверьте Экспорт и получение объекта

Данные после Записать()
Норма

Реквизиты в базе изменились

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

Данные прежние — вызов Записать() пропущен или объект не тот

Форма после серверного вызова
Норма

На форме видны новые значения

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

Форма показывает старое — нет ЗначениеВРеквизитФормы

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

Можно ли вызвать процедуру модуля объекта без ПолучитьОбъект()?

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

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

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

Как вызвать процедуру модуля объекта из внешней обработки?

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

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

Нет, ПолучитьОбъект() недоступен в клиентском контексте. Создайте серверную процедуру (в общем модуле с признаком «Сервер» или в модуле формы с директивой &НаСервере) и вызывайте её с клиента.

Чем модуль менеджера отличается от модуля объекта?

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

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

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

Итог

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

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