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