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

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

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

Как обратиться к модулю объекта в 1С: методы ПолучитьОбъект, ДанныеФормыВЗначение, общие модули, типичные ошибки и примеры кода для разработчика.

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

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

Что такое модуль объекта и чем он отличается от других модулей

Модуль объекта существует в контексте конкретного экземпляра данных. Когда вы пишете код в модуле объекта справочника «Номенклатура», этот код выполняется относительно конкретного элемента справочника — с доступом к его реквизитам через ЭтотОбъект или напрямую по имени реквизита. Без экземпляра объекта модуль просто не существует в памяти.

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

Обращение к модулю объекта существующего элемента

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

СсылкаНаЭлемент = Справочники.Номенклатура.НайтиПоКоду("000000001");

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

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

ОбъектНоменклатура.Записать();

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

Обращение к модулю объекта нового элемента

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

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

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

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

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

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

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

В управляемых формах прямой доступ к объекту данных ограничен: на клиенте доступны только данные формы, а не сам объект. Чтобы вызвать метод модуля объекта, нужно перейти в серверный контекст и преобразовать данные формы в объект с помощью ДанныеФормыВЗначение():

&НаСервере

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

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

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

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

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

Обратное преобразование ЗначениеВРеквизитФормы() обязательно, если изменения должны отобразиться на форме. Типичная ошибка — вызвать метод объекта, но забыть вернуть данные обратно в форму: пользователь не увидит результата, хотя в памяти сервера он есть.

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

Альтернатива: перенос логики в общий модуль

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

Критерий выбора простой: если метод работает с реквизитами объекта через ЭтотОбъект — ему место в модуле объекта. Если метод получает ссылку или набор параметров и работает независимо — в общем модуле. Смешивание подходов приводит к дублированию кода и затрудняет сопровождение.

Сравнение вариантов

Метод в модуле объекта

Подходит, когда логика неразрывно связана с данными конкретного объекта. Требует получения объекта, что затратно при массовых вызовах.

Общий модуль

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

Модуль менеджера объекта

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

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

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

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

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

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

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

Дополнительно проверьте, что после Записать() не возникло исключений: оберните вызов в Попытка...Исключение и выведите описание ошибки через ОписаниеОшибки(). Это особенно важно в фоновых заданиях, где ошибки иначе теряются.

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

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

Точка останова в методе модуля объекта
Норма

Отладчик останавливается при вызове

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

Точка не срабатывает — метод не экспортный или вызван не у объекта

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

Изменения видны в базе и на форме

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

Данные не изменились — запись не выполнена или объект не возвращён в форму

Журнал регистрации
Норма

Нет ошибок выполнения

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

Исключения при записи — смотреть обработчики событий объекта

Итог

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

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

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

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

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

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

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

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

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

Нужно ли вызывать ПолучитьОбъект(), если мне нужно только прочитать реквизиты?

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

Работает ли вызов метода модуля объекта в фоновом задании?

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