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

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

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

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

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

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

Что такое модуль объекта и когда функции доступны извне

Модуль объекта открывается в конфигураторе: правой кнопкой по объекту метаданных (например, документу «РеализацияТоваров») → «Открыть модуль объекта». Код в нём исполняется в контексте конкретного экземпляра объекта, поэтому внутри модуля доступны реквизиты, табличные части и переменная ЭтотОбъект.

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

Функция РассчитатьСуммуСоСкидкой(ПроцентСкидки) Экспорт

Возврат СуммаДокумента * (100 - ПроцентСкидки) / 100;

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

Директивы компиляции (&НаСервере, &НаКлиенте) в модуле объекта не используются — он целиком компилируется в контексте, определяемом платформой: в файловом варианте и на сервере — на сервере, в тонком и веб-клиенте модуль объекта недоступен напрямую.

Как вызвать функцию модуля объекта из другого модуля

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

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

ИтоговаяСумма = ОбъектДокумента.РассчитатьСуммуСоСкидкой(10);

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

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

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

&НаСервере

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

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

Итог = ТекущийОбъект.РассчитатьСуммуСоСкидкой(10);

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

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

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

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

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

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

Функция ИтоговаяСумма() Экспорт

Возврат РассчитатьСуммуСоСкидкой(СкидкаПоКарте);

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

Явное обращение через ЭтотОбъект.РассчитатьСуммуСоСкидкой(...) тоже допустимо, но избыточно. Переменную ЭтотОбъект обычно используют, когда нужно передать ссылку на сам объект в другую процедуру — например, в обработчик подписки на событие или в общий модуль.

Обращение из обработчиков событий и подписок

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

Процедура ДокументПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт

Если Источник.ПроверитьЗаполнениеТабличнойЧасти() Тогда

// дополнительная логика

КонецЕсли;

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

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

Типичные ошибки при обращении к функции

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

Вторая группа ошибок связана с контекстом исполнения. Модуль объекта недоступен на клиенте в тонком и веб-клиенте: вызов из клиентской процедуры формы без серверного вызова невозможен. Нужно перенести вызов в серверную процедуру с директивой &НаСервере. Также функция не будет видна снаружи, если забыто слово Экспорт или оно написано после тела функции, а не в заголовке.

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

Производительность и альтернативы

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

Где размещать функцию

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

Логика неотделима от данных конкретного экземпляра: проверки, расчёты по реквизитам и табличным частям. Ограничение — требует получения объекта и недоступна на клиенте

Общий модуль

Универсальные расчёты, работа с произвольными данными, массовая обработка через запросы. Нет доступа к контексту объекта напрямую

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

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

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

Как проверить, что вызов работает

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

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

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

Заголовок функции
Норма

Есть слово Экспорт после списка параметров

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

Экспорт отсутствует или стоит внутри тела функции

Тип переменной вызова
Норма

СправочникОбъект / ДокументОбъект (видно в табло отладчика)

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

СправочникСсылка / ДокументСсылка

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

Вызов выполняется на сервере или в толстом клиенте

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

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

Отображение изменений
Норма

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

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

Данные изменились в объекте, но форма осталась прежней

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

FAQ

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

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

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

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

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

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

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

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

Нужно ли получать объект, если вызов идёт из модуля формы этого же объекта?

На сервере данные формы хранятся как ДанныеФормыСтруктура, а не как объект конфигурации, поэтому преобразование через РеквизитФормыВЗначение("Объект") всё равно необходимо. Без него экспортные функции модуля объекта недоступны.

Итог

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

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