Разработка и Конфигурация · 11 мин
Как вызвать экспортную процедуру модуля объекта в 1С
Разбираем, как вызвать экспортную процедуру модуля объекта в 1С: синтаксис, получение объекта, отличия от общих модулей, типичные ошибки и примеры кода.
Экспортная процедура модуля объекта — это метод, описанный в модуле конкретного объекта конфигурации (справочника, документа, обработки, плана счетов и т.д.) с ключевым словом Экспорт. Такое слово делает процедуру видимой извне: её можно вызвать из других модулей, обработок, внешних отчётов и даже через COM-соединение. Без Экспорт процедура остаётся локальной и доступна только внутри своего модуля.
Ключевой момент, который часто упускают начинающие разработчики: процедура модуля объекта вызывается не «по имени объекта метаданных», а через конкретный экземпляр — объект в памяти. Нельзя написать Справочники.Номенклатура.МояПроцедура() — сначала нужно получить объект (создать новый или прочитать существующий по ссылке), и только у этого объекта вызвать метод.
Ниже разобраны все рабочие сценарии: вызов для нового и существующего объекта, вызов из модуля формы, из внешней обработки, через COM, а также типичные ошибки вроде «Метод объекта не обнаружен».
Что такое экспортная процедура и где она объявляется
Модуль объекта существует у прикладных объектов: справочников, документов, планов видов характеристик, планов счетов, планов видов расчёта, бизнес-процессов, задач, обработок и отчётов. В нём размещают бизнес-логику, привязанную к данным конкретного объекта: проверки заполнения, пересчёты, формирование движений, вспомогательные операции.
Чтобы процедура стала доступной извне, её объявляют с ключевым словом Экспорт:
Процедура ПересчитатьСуммуДокумента(КурсПересчета = 1) Экспорт
СуммаДокумента = Товары.Итог("Сумма") * КурсПересчета;
КонецПроцедуры
Слово Экспорт ставится после списка параметров, перед закрывающей скобкой объявления. Если его опустить, процедура будет видна только внутри модуля объекта, и любая попытка внешнего вызова завершится ошибкой «Метод объекта не обнаружен».
Как получить объект для вызова метода
Процедура модуля объекта работает в контексте данных конкретного экземпляра, поэтому первый шаг — получить этот экземпляр. Способ зависит от того, существует ли объект в базе.
Существующий объект: получение по ссылке
Если объект уже записан в базу, у вас обычно есть ссылка на него. Объект получают методом ПолучитьОбъект():
ДокОбъект = ДокументСсылка.ПолучитьОбъект();
ДокОбъект.ПересчитатьСуммуДокумента(75.5);
ДокОбъект.Записать();
Здесь важно понимать: изменения, которые процедура внесла в объект, живут только в памяти. Если процедура меняет реквизиты и результат нужно сохранить, после вызова требуется Записать(). Если процедура только вычисляет и возвращает значение (функция), записывать объект не нужно.
Новый объект: создание через менеджер
Для ещё не записанного объекта используют методы менеджера типа:
НовыйДок = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
НовыйДок.Дата = ТекущаяДатаСеанса();
НовыйДок.ЗаполнитьПоУмолчанию(); // экспортная процедура из модуля объекта
Аналогично для справочников — Справочники.Номенклатура.СоздатьЭлемент() или СоздатьГруппу(), для обработок — Обработки.ИмяОбработки.Создать().
- 1Убедитесь, что процедура в модуле объекта объявлена с ключевым словом Экспорт
- 2Получите объект: Ссылка.ПолучитьОбъект() или Менеджер.СоздатьДокумент()/СоздатьЭлемент()
- 3Вызовите метод: Объект.ИмяПроцедуры(Параметры)
- 4Если процедура меняет данные — выполните Объект.Записать()
- 5Проверьте результат: значения реквизитов, возвращаемое значение, отсутствие исключений
Вызов из модуля формы и из другого объекта
В управляемой форме объекта данные представлены реквизитом формы (например, Объект типа ДанныеФормыСтруктура), и это не объект в строгом смысле. Прямой вызов Объект.МояПроцедура() на клиенте не сработает. Нужен серверный контекст и преобразование:
&НаСервере
Процедура ВыполнитьПересчетНаСервере()
ДокОбъект = РеквизитФормыВЗначение("Объект");
ДокОбъект.ПересчитатьСуммуДокумента();
ЗначениеВРеквизитФормы(ДокОбъект, "Объект");
КонецПроцедуры
Обратное преобразование ЗначениеВРеквизитФормы обязательно, иначе изменения не отобразятся в форме. Учтите, что оба преобразования — затратные операции, поэтому не стоит вызывать их в цикле.
Вызов из модуля другого объекта или из общего модуля ничем не отличается от базового сценария: получаете объект по ссылке и вызываете метод. Единственное ограничение — общий модуль, работающий в контексте клиента, не может получить объект (метод ПолучитьОбъект() доступен только на сервере, в толстом клиенте и во внешнем соединении).
Вызов из внешней обработки и через COM
Из внешней обработки (файл .epf) вызов выполняется так же, как из конфигурации, если обработка открыта внутри информационной базы: ссылка, ПолучитьОбъект(), вызов метода. Ограничений по доступу к экспортным процедурам объектов конфигурации у внешних обработок нет.
При подключении через COM (V83.COMConnector) логика сохраняется, но синтаксис проходит через объект соединения:
// Внешний код, например VBS или другая база 1С
Док = Соединение.Documents.РеализацияТоваровУслуг.СоздатьДокумент();
Док.ЗаполнитьПоУмолчанию();
Док.Write();
Через COM экспортные процедуры объектов доступны, однако вызов каждого метода — это обращение по сети, поэтому массовые операции лучше оформлять одной серверной функцией в общем модуле и вызывать её целиком.
Отличие от общих модулей и модуля менеджера
Частая дилемма: где разместить логику — в модуле объекта, модуле менеджера или общем модуле. Выбор влияет на способ вызова.
| Место размещения | Как вызывается | Когда выбирать |
|---|---|---|
| Модуль объекта (Экспорт) | Объект.Метод() — нужен экземпляр | Логика работает с данными конкретного объекта |
| Модуль менеджера (Экспорт) | Справочники.Имя.Метод() / Документы.Имя.Метод() | Операции над типом в целом: поиск, подбор, печатные формы |
| Общий модуль (Экспорт) | ИмяМодуля.Метод() | Универсальная логика, не привязанная к типу объекта |
Если процедура не использует реквизиты и табличные части конкретного объекта, её правильнее вынести в общий модуль или модуль менеджера — тогда не понадобится получать объект, что сэкономит обращения к базе.
Где разместить процедуру
Подходит, если метод читает или меняет реквизиты и табличные части конкретного экземпляра. Требует ПолучитьОбъект() — лишнее чтение из базы
Подходит для операций уровня типа: поиск дублей, создание по шаблону. Вызывается без экземпляра объекта
Подходит для универсальных алгоритмов. Можно включить флаг Сервер и вызывать откуда угодно без создания объектов
Типичные ошибки и как их исправить
Самая распространённая ошибка — «Метод объекта не обнаружен: ИмяПроцедуры». Причины: забыто слово Экспорт, опечатка в имени, процедура размещена не в модуле объекта, а в модуле формы, либо вызов идёт у ссылки (Ссылка.Метод()), а не у объекта. Ссылка имеет только стандартные свойства и метод ПолучитьОбъект() — пользовательских методов у неё нет.
Вторая группа проблем — контекст выполнения. Попытка вызвать ПолучитьОбъект() в клиентской процедуре управляемой формы приводит к ошибке компиляции или выполнения. Решение — перенести вызов в серверную процедуру с директивой &НаСервере.
Третья типичная ситуация: процедура отработала, но изменения «пропали». Причина почти всегда в том, что после вызова не выполнен Записать(), либо в форме не сделано обратное преобразование ЗначениеВРеквизитФормы.
Проверка результата и отладка
Проверить корректность вызова можно несколькими способами. В конфигураторе поставьте точку останова на первой строке экспортной процедуры и запустите отладку — если выполнение не останавливается, метод не вызывается (неверное имя, отсутствует Экспорт или вызов идёт по другому пути).
Для процедур, меняющих данные, контролируйте два состояния: значения реквизитов объекта в памяти сразу после вызова и данные в базе после Записать(). Расхождение между ними указывает на проблемы с записью — например, сработала проверка заполнения или нарушена уникальность.
Как проверить результат
Отладчик останавливается внутри экспортной процедуры
Ошибка «Метод объекта не обнаружен» или отладчик не срабатывает
После Записать() реквизиты в базе соответствуют ожиданиям
Объект не записан, исключение при записи
Поля формы обновились после ЗначениеВРеквизитФормы
В форме старые значения при корректных данных объекта
При массовых вызовах (например, пересчёт тысяч документов) оборачивайте вызовы в транзакцию осмысленно: одна транзакция на весь пакет рискует длинными блокировками, транзакция на каждый объект — безопаснее, но медленнее. На больших объёмах тестируйте обработку на копии базы.
FAQ
Можно ли вызвать процедуру модуля объекта, не получая объект?
Нет. Методы модуля объекта существуют только в контексте экземпляра. Если получение объекта нежелательно (например, из-за лишнего чтения из базы), перенесите логику в модуль менеджера — его экспортные процедуры вызываются как Документы.Имя.Метод() без создания экземпляра.
Почему возникает ошибка «Метод объекта не обнаружен»?
Четыре основные причины: в объявлении процедуры нет слова Экспорт; вызов выполняется у ссылки, а не у объекта; опечатка в имени метода; процедура находится в модуле формы, а не в модуле объекта. Проверяйте их в этом порядке.
Как вызвать экспортную процедуру из управляемой формы?
В серверной процедуре формы преобразуйте реквизит формы в объект: ДокОбъект = РеквизитФормыВЗначение("Объект"), вызовите метод, затем верните данные через ЗначениеВРеквизитФормы(ДокОбъект, "Объект"). На клиенте прямой вызов невозможен.
Чем экспортная функция отличается от экспортной процедуры при вызове?
Только наличием возвращаемого значения: функцию вызывают с присвоением результата (Результат = Объект.РассчитатьИтог()), процедуру — как самостоятельный оператор. Правила получения объекта и ключевое слово Экспорт одинаковы.
Доступны ли экспортные процедуры объекта через COM-соединение?
Да, через V83.COMConnector экспортные методы объектов вызываются так же, как в обычном коде. Однако каждый вызов идёт по сети, поэтому массовые операции эффективнее оформить одной серверной функцией в общем модуле и вызывать её один раз.
Куда лучше поместить логику — в модуль объекта или в общий модуль?
Если код работает с реквизитами и табличными частями конкретного экземпляра — в модуль объекта. Если алгоритм универсален или оперирует ссылками без чтения данных — в общий модуль или модуль менеджера: это упрощает вызов и избавляет от лишних обращений к базе.
Что важно запомнить
Экспортная процедура модуля объекта вызывается только у экземпляра объекта: получите его через Ссылка.ПолучитьОбъект() или создайте через менеджер, затем вызовите Объект.Метод(). В объявлении обязательно слово Экспорт, в управляемой форме нужно преобразование РеквизитФормыВЗначение, а после изменения данных — Записать(). Если объект получать незачем, размещайте логику в модуле менеджера или общем модуле.