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