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

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

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

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

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

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

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

Что такое экспортная процедура и где она объявляется

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

Чтобы процедура стала доступной извне, её объявляют с ключевым словом Экспорт:

Процедура ПересчитатьСуммуДокумента(КурсПересчета = 1) Экспорт

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

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

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

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

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

Существующий объект: получение по ссылке

Если объект уже записан в базу, у вас обычно есть ссылка на него. Объект получают методом ПолучитьОбъект():

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

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

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

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

Новый объект: создание через менеджер

Для ещё не записанного объекта используют методы менеджера типа:

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

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

НовыйДок.ЗаполнитьПоУмолчанию(); // экспортная процедура из модуля объекта

Аналогично для справочников — Справочники.Номенклатура.СоздатьЭлемент() или СоздатьГруппу(), для обработок — Обработки.ИмяОбработки.Создать().

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

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

В управляемой форме объекта данные представлены реквизитом формы (например, Объект типа ДанныеФормыСтруктура), и это не объект в строгом смысле. Прямой вызов Объект.МояПроцедура() на клиенте не сработает. Нужен серверный контекст и преобразование:

&НаСервере

Процедура ВыполнитьПересчетНаСервере()

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

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

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

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

Обратное преобразование ЗначениеВРеквизитФормы обязательно, иначе изменения не отобразятся в форме. Учтите, что оба преобразования — затратные операции, поэтому не стоит вызывать их в цикле.

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

Вызов из внешней обработки и через COM

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

При подключении через COM (V83.COMConnector) логика сохраняется, но синтаксис проходит через объект соединения:

// Внешний код, например VBS или другая база 1С

Док = Соединение.Documents.РеализацияТоваровУслуг.СоздатьДокумент();

Док.ЗаполнитьПоУмолчанию();

Док.Write();

Через COM экспортные процедуры объектов доступны, однако вызов каждого метода — это обращение по сети, поэтому массовые операции лучше оформлять одной серверной функцией в общем модуле и вызывать её целиком.

Отличие от общих модулей и модуля менеджера

Частая дилемма: где разместить логику — в модуле объекта, модуле менеджера или общем модуле. Выбор влияет на способ вызова.

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

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

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

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

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

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

Подходит для операций уровня типа: поиск дублей, создание по шаблону. Вызывается без экземпляра объекта

Общий модуль

Подходит для универсальных алгоритмов. Можно включить флаг Сервер и вызывать откуда угодно без создания объектов

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

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

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

Третья типичная ситуация: процедура отработала, но изменения «пропали». Причина почти всегда в том, что после вызова не выполнен Записать(), либо в форме не сделано обратное преобразование ЗначениеВРеквизитФормы.

Типичные ошибки
01
Вызов метода у ссылки вместо объекта — ошибка «Метод объекта не обнаружен»; сначала выполните ПолучитьОбъект()
02
Пропущено слово Экспорт в объявлении — процедура невидима снаружи
03
Вызов ПолучитьОбъект() на клиенте — ошибка контекста; перенесите код в серверную процедуру
04
Забыт Записать() после изменений — данные не сохраняются в базе
05
В форме не выполнено ЗначениеВРеквизитФормы — пользователь не видит результат пересчёта

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

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

Для процедур, меняющих данные, контролируйте два состояния: значения реквизитов объекта в памяти сразу после вызова и данные в базе после Записать(). Расхождение между ними указывает на проблемы с записью — например, сработала проверка заполнения или нарушена уникальность.

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

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

Вызов метода
Норма

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

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

Ошибка «Метод объекта не обнаружен» или отладчик не срабатывает

Изменение данных
Норма

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

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

Объект не записан, исключение при записи

Отображение в форме
Норма

Поля формы обновились после ЗначениеВРеквизитФормы

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

В форме старые значения при корректных данных объекта

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

FAQ

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

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

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

Четыре основные причины: в объявлении процедуры нет слова Экспорт; вызов выполняется у ссылки, а не у объекта; опечатка в имени метода; процедура находится в модуле формы, а не в модуле объекта. Проверяйте их в этом порядке.

Как вызвать экспортную процедуру из управляемой формы?

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

Чем экспортная функция отличается от экспортной процедуры при вызове?

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

Доступны ли экспортные процедуры объекта через COM-соединение?

Да, через V83.COMConnector экспортные методы объектов вызываются так же, как в обычном коде. Однако каждый вызов идёт по сети, поэтому массовые операции эффективнее оформить одной серверной функцией в общем модуле и вызывать её один раз.

Куда лучше поместить логику — в модуль объекта или в общий модуль?

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

Итог

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

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