Модуль объекта и модуль менеджера. Отличия

Практически у всех объектов конфигурации есть модуль менеджера, и для большинства объектов модуль объекта. Часто начинающие программисты не понимают различия в назначении этих двух модулей.
Понимание в различии их назначения позволяет писать более правильный по структуре программный код, а в некоторых случаях сэкономить ресурсы сервера 1С и увеличить производительность прикладного решения.
В статье рассмотрим принципиальные различия между этими модулями как с теоретической стороны, так и на конкретном практическом примере.
Теория
Обратимся к основам объектно-ориентированного программирования (ООП) и проведем аналогию с нашим примером. В ООП методы для объектов можно разделить на статические (static) и простые . Простые методы могут быть вызваны только для конкретного объекта, доступ к которому мы имеем в текущем контексте программного кода. Статические методы не имеют непосредственного доступа к данным объектов. Для обращения к объекту первоначально нужно создать его экзмемпляр. То же самое относится к платформе 1С:Предприятие 8.x.

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

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

В случае использования метода из модуля менеджера мы можем обращаться к данным справончника «Товары» без получения объекта для каждой ссылки. Поскольку получения объекта означает получение всех данных из базы данных по элементу справочника и помещение полученных данных в оперативную память, то реализация задачи вторым способом положительно повлияет на производительность. Ведь в таком случае мы будем использовать минимум ресурсов (оперативной памяти) серверной машины.
Что же использовать?
Как всегда, все зависит от конкретной задачи. Если нужно выполнить печать документа, то более оптимальный вариант — использовать модуль менеджера. Если нужно заполнять объект, например, внешней обработкой заполнения табличных частей, то в таком случае процедуры и функции лучше располагать в модуле объекта, поскольку их работа предполагает именно с объектом.
В типовой конфигурации «Управление торговлей» версии 11 повсеместно используетмся модуль менеджера для печати документов. Если посмотреть на конфигурацию «Управление производственным предприятием», то модуль менеджера практически не используется, так как конфигурация писалась в старых версиях платформы, где полноценной поддержки этого механизма не было.
Модуль менеджера объекта
Пожалуй, начнем сразу с практического примера.
В справочник Контрагенты нам необходимо заносить информацию о поставщиках, покупателях, банках, налоговых органах, различных фондах и пр. Для каждого вида контрагента нас интересует разная информация.
Создадим функцию, возвращающую список «важных» реквизитов в зависимости от вида контрагента:
Код 1C v 8.2 УП
Где же ее правильнее разместить?
Напрашивается вариант — в процедуре Модуля объекта «ПередЗаписью()». Тем самым мы на этапе записи будем контролировать правильность заполнения нужных нам реквизитов. С точки зрения создания, изменения элемента справочника, нас все устраивает. Но если нам необходимо, чтобы некоторые менеджеры заносились контрагентов в ИБ без контроля, а спустя какое-то время мы будем выполнять проверку на корректность заполнения данных в справочнике. Тогда нужно будет написать обработку. И в этой обработке, перебирая элементы, проверять заполнение реквизитов. Т.о. эту функцию придется разместить в коде обработки. А это получается дублирование кода, со всеми вытекающими проблемами. Можно получать объект каждого элемента, обращаться к функции, расположенной в его Модуле объекта. Но это будет дополнительные обращения к БД, тогда как в обработке нам достаточно только ссылок.
Можно выйти из этой ситуации создав Общий модуль «РаботаСКонтрагентами» и разместить в нем функцию возвращающую список реквизитов для проверки. В этом случае будем обращаться так «РаботаСКонтрагентами.ПолучитьСписокВажныхРеквизитов(ВидКонтрагента)».
Но! На платформе 8.2 как раз для решения подобной задачи и был создан Модуль менежера. Там и разместим нашу функцию. А обращаться мы будем: «Справочники.Контрагенты.ПолучитьСписокВажныхРеквизитов(ВидКонтрагента)».
Т.о. на ряду с предопределенными методами, мы можем самостоятельно разработать свои процедуры и обращаться к ним как методам Менеджера объекта, через точку. У нас отпадает необходимость создавать «тематические» внешние модули такие как «Работа с Контрагентами», «Процедуры Номенклатуры».
Обратимся теперь к теории, чтобы «разложить все по полочкам».
Руководство разработчика дает нам следующее описание: «Модуль менеджера существует у всех прикладных объектов и предназначен для управления этим объектом как объектом конфигурации. Модуль менеджера позволяет расширить функциональность менеджеров за счет введения процедур и функций на встроенном языке. Фактически это позволяет описать методы для объекта конфигурации, которые относятся не к конкретному экземпляру объекта базы данных, а к самому объекту конфигурации». Именно это мы и разобрали в нашем практическом примере.
Отобразим иерархию классов прикладных объектов на примере Справочников: 
Т.е. мы видим, что появление «Модуля менеджера объекта» логично расширяет свойства класса СправочникМенеджер, так же как экспортные процедуры «Модуля объекта» расширяют методы класса СправочникОбъект. Нужно ли было создавать «Модуль прикладного объекта Справочники (Документы, Перечисления)». Наверное нет. Достаточно трудно придумать какие-либо задачи для единой обработки всех видов справочников.
Кроме возможности расширения методов класса, в модуле менеджера существует предопределенная процедура События Код 1C v 8.2 УП . Она возникает на сервере перед стандартным формированием списка при вводе по строке, автоподборе текста и быстром выборе, а также при выполнении метода «ПолучитьДанныеВыбора()».
Так же хочу обратить внимание. При использовании конструктора печати прикладного объекта, платформа расположит процедуру формирования табличного документа непосредственно в Модуле менеджера. И это логично. Теперь, чтобы получить табличный документ элемента справочника нет необходимости получать объект. Достаточно кода: Код 1C v 8.2 УП .
Программные модули платформы 1С: предназначение и свойства
Программный модуль 1С представляет собой текст на встроенном языке 1С:Предприятия, расположенный в определенном месте конфигурации.
Виды программных модулей:
-
принадлежат всей конфигурации в целом. В отличие от модуля приложения (см. ниже), их может быть несколько. Общие модули не могут содержать объявлений переменных, и в них нет раздела основной программы, таким образом, они состоят только из процедур и функций. (обычного и управляемого) — это модуль, который относится ко всей конфигурации в целом и может быть только один (является аналогом глобального модуля в версии 7.7). Он отвечает за пользовательскую сессию (сеанс) работы с 1С:Предприятие 8. — используется вместо модуля приложения в том случае, если конфигурация запускается через COM-соединение, а не в режиме клиентской сессии. — собственный модуль некоторых прикладных объектов конфигурации (например, модуль документа РасходнаяНакладная, модуль справочника Номенклатура). Не путать с модулями форм этих объектов! . — модуль, в котором определяется поведение формы и действия, выполняемые из нее (например, открытие других форм). — для переопределения стандартного события выбора, которое возникает в момент ввода по строке и для расширение функционала менеджера.
- Модули команд.
- Модули набора записей.
Открыть общий модуль 1С:

Открыть модуль объекта 1С:

Открыть модуль формы 1С:

Разделы программного модуля
Любой программный модуль, за исключением общих модулей, состоит из следующих разделов:
- раздел объявления переменных;
- раздел процедур и функций;
- раздел основной программы.
- у общих модулей;
- у модулей сеанса.
Методические рекомендации по наполнению (структуре) программных модулей 1С.
Контекст программного модуля
Контекст — в 1С:Предприятии 8 обозначает окружение модуля, т. е. доступность для него переменных, объектов, свойств, методов и событий.
- Глобальный контекст, доступный во всех остальных контекстах, состоит из следующих частей:
- свойства, методы и события глобального контекста (например, свойство РабочаяДата);
- системные перечисления и системные наборы значений (например, КодВозвратаДиалога и Символы).
- Контекст модуля приложения (или модуля внешнего соединения), в котором:
- доступны экспортируемые процедуры и функции общих модулей .
- Контекст общего модуля, в котором:
- доступны экспортируемые процедуры и функции других общих модулей ;
- недоступны экспортируемые переменные, процедуры и функции модуля приложения .
- Контекст модуля объекта, в котором есть доступ к реквизитам и табличным частям объекта, а также его методам и событиям (например, в модуле документа РасходнаяНакладная доступны реквизиты документа и его табличные части, можно вызывать методы документа и обрабатывать события).
- Контекст модуля формы, в котором доступны реквизиты формы, а также ее свойства, методы и события. Если у формы назначен основной реквизит, то в модуле формы становятся доступны свойства и методы прикладного объекта, используемого в качестве основного реквизита, а также экспортируемые переменные, процедуры и функции модуля этого прикладного объекта.
Правила видимости экспортируемых переменных, процедур и функций различных модулей 1С:
- В общем модуле недоступны экспортируемые переменные, процедуры и функции модуля приложения (модуля внешнего соединения).
- В модуле приложения (модуле внешнего соединения) доступны экспортируемые процедуры и функции общих модулей.
- В общих модулях доступны экспортируемые процедуры и функции других общих модулей.
- В модулях прикладных объектов и модулях форм доступны экспортируемые переменные, процедуры и функции модуля приложения (модуля внешнего соединения), а также экспортируемые процедуры и функции общих модулей.
- Если у формы назначен основной реквизит, то контекст модуля формы содержит дополнительные свойства и методы, связанные с основным реквизитом (например, в модуле формы элемента справочника Номенклатура доступны свойства и методы объекта СправочникОбъект.Номенклатура).
» Экспорт « — необязательное ключевое слово, которое указывает на то, что процедура является доступной из других программных модулей.

Выполняться модули 1С могут (в общем случае):
- на клиенте;
- на сервере;
- как на стороне клиента, так и на стороне сервера.
Модуль приложения 1С
Модуль приложения 1С предназначен для объявления глобальных переменных, а также обработки событий:
- запуска приложения и
- завершения его работы.
Модуль приложения содержит обработчики, позволяющие перехватить и обработать внешние события от оборудования (например, события от торгового или фискального оборудования).
ВАЖНО! В модуле приложения отслеживается именно интерактивный запуск системы (т.е. когда создается окно программы); он не будет работать, если запуск программы 1С осуществляется, например, в режиме com-соединения, так как в этом случае окно программы не создается.
Процедуры, функции и переменные модуля приложения могут быть описаны как экспортные. Все переменные и методы, которые помечены как экспортные будут доступны в любом модуле конфигурации, работающем на стороне клиента. Однако для описания общих алгоритмов рекомендуется использовать «Общие модули», что позволит снизить время компиляции модуля и, соответственно, время запуска приложения.
Расширить контекст модуля приложения можно за счет методов общих модулей, для которых установлено свойство «Вызов сервера».
Виды модуля приложения:
- модуль управляемого приложения (события этого модуля обрабатываются при запуске тонкого клиента, толстого клиента и веб-клиента);
- модуль обычного приложения (работает при запуске толстого клиента в режиме обычного приложения).
ВАЖНО! Если приложение работает и в режиме управляемого приложения, и в режиме обычного приложения, то необходимо описывать процедуры-обработчики как для модуля управляемого приложения, так и для модуля обычного приложения.
Модуль управляемого приложения можно открыть:
- командой из контекстного меню корневого узла конфигурации;
- из палитры свойств корневого элемента конфигурации.


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



Обработка модуля приложения 1С
В модуле приложения можно размещать стандартные разделы модуля:
- раздел объявления переменных;
- раздел описания произвольных процедур и функций;
- раздел основной программы.
Список событий, которые можно обрабатывать, для управляемого и обычного приложения одинаков. Но кроме произвольных процедур и функций в модуле могут быть расположены специальные обработчики событий. Список доступных обработчиков можно посмотреть, если при открытом модуле вызвать список процедур и функций текущего модуля. В раскрывшемся окне «Процедуры и функции» отображаются:
- все процедуры и функции данного модуля;
- события, для которых обработчики еще не созданы.


Когда выполняется обработчик события “перед”, считается, что действие еще не совершено. Когда выполняется обработчик события “при” – действие уже совершено.
- события, связанные с началом работы системы:
- < ПередНачаломРаботыСистемы > возникает в момент запуска Предприятия 8.3 до появления приложения на экране; если параметр «Отказ» примет значение Истина, то приложение не запустится.
- < ПриНачалеРаботыСистемы > предполагает, что окно уже создано, и в этом случае можно, например, отобразить какую-то специальную форму. Отказаться от запуска уже нельзя.
- события, связанные с завершением работы системы:
- < ПередЗавершениемРаботыСистемы > — приложение еще открыто и можно отказаться от его завершения.
- < ПриЗавершенииРаботыСистемы > — окно приложения уже закрылось; возможно выполнить лишь дополнительные действия, например, по удалению файлов или отправке электронного письма.
- обработка внешнего события (например, события торгового оборудования):
- < ОбработкаВнешнегоСобытия >
ВАЖНО! Процедуры-обработчики событий, расположенные в модуле приложения, модуле внешнего соединения, модуле прикладного объекта должны называться точно так, как называются соответствующие события. (подробнее)
В модуле Управляемого приложения не указываются директивы компиляции процедур и функций, так как модуль целиком компилируется на стороне Клиента . Это означает, что в процедурах и функциях модуля мы не сможем непосредственно обратиться, например, к справочникам. Если из модуля Управляемого приложения необходимо сделать Серверный вызов, то для этого нужно будет создавать специальные Общие модули с выставленным флагом «Вызов Сервера».
В модуле Обычного приложения подобных ограничений нет, так как данный модуль будет компилироваться при загрузке Толстого клиента. В Толстом клиенте доступны практически все типы данных.
Модуль внешнего соединения
Модуль внешнего соединения срабатывает, когда запуск приложения происходит в режиме com-соединения и предназначен для обработки событий:
- запуска приложения и
- завершения его работы.
Как и в модуле приложения, здесь доступны разделы описания переменных, методов и раздел основной программы. Процедуры, функции и глобальные переменные, определенные в модуле внешнего соединения с ключевым словом «Экспорт» становятся, как и в случае модуля приложения, частью глобального контекста.
Отличие модуля внешнего соединения от модуля приложения:
- в режиме com-соединения вся работа с информационной базой происходит на стороне сервера;
- модуль внешнего соединения компилируется исключительно на сервере, поэтому в нем не доступны экспортные переменные и методы общих клиентских модулей.
Сам процесс внешнего соединения – это процесс неинтерактивный. В этом режиме происходит программная работа с информационной базой и не происходит открытия окна приложения, что накладывает определенные ограничения на использование методов, предназначенных для интерактивной работы. В этом режиме нельзя использовать вызовы диалоговых форм, предупреждающих сообщений и т.п. Они просто не сработают.
< ПриНачалеРаботыСистемы > — действия, выполняемые при инициализации соединения.
< ПриЗавершенииРаботыСистемы > — действия, выполняемые при завершении соединения.


ВАЖНО! Процедуры-обработчики событий, расположенные в модуле приложения, модуле внешнего соединения, модуле прикладного объекта должны называться точно так, как называются соответствующие события. (подробнее)
Модуль сеанса
Модуль сеанса — это узкоспециализированный модуль, предназначенный исключительно для инициализации параметров сеанса и выполняющийся в любом режиме запуска приложения .
Особенности модуля сеанса:
- Исполнение происходит после начала исполнения модуля приложения (модуля внешнего соединения).
- Запускается в привилегированном режиме (не выполняется проверка прав доступа при обращении к базе данных).
- Компилируется только на сервере.
- Нет раздела описания переменных и раздела основной программы.
- Нельзя описывать экспортные методы, процедуры и функции, используется только для установки параметров сеанса.
Событие < УстановкаПараметровСеанса >, единственное для этого модуля, выполняется самым первым (даже раньше события модуля приложения < ПередНачаломРаботыСистемы >).


- обработчик УстановкаПараметровСеанса может неоднократно вызываться в процессе работе системы (например, когда мы обращаемся к не инициализированным параметрам);
- данный модуль компилируется в привилегированном режиме, т.е. в нем не осуществляется контроль прав доступа;
- мы не можем быть полностью уверены, что запуск системы будет произведен, и в случае отказа приложения пытаемся выполнить какие-то действия с базой данных.
Общие модули
Общие модули содержат программный код (процедуры и функции), который вызывается из других мест конфигурации (используемый в других программных модулях), и может принадлежать всей конфигурации.
Модуль формы 1C
Модуль формы 1C предназначен для обработки:
- событий, связанных непосредственно с самой формой (например, открытие или закрытие), а также
- событий, связанных с действиями пользователя (например, вводом данных и обработкой корректности их ввода).
Модуль формы компилируется:
- обычной — на клиенте;
- управляемой — четко разграничен по контексту выполнения, поэтому все переменные и методы должны иметь директиву компиляции (если директива в явном виде не указана, тогда эта переменная или метод будут скомпилированы на стороне сервера).
В модуле формы доступны разделы описания переменных и методов, а также раздел основной программы.
К стандартным событиям формы можно обратиться:
- через список процедур и функций (Ctrl+Alt+P) либо
- в палитре свойств самой формы.


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