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

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

Зачем нужен модуль менеджера в 1С и как его использовать

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

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

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

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

Что такое модуль менеджера и где он находится

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

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

Какие задачи решает модуль менеджера

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

  • Поиск и создание элементов. Функции вида «НайтиИлиСоздатьПоИНН», «ПолучитьЭлементПоШтрихкоду» — классическое содержимое модуля менеджера справочника.
  • Печатные формы. В типовых конфигурациях процедуры Печать, ДобавитьКомандуПечати, функции формирования табличных документов традиционно размещаются именно здесь.
  • Обработчики получения данных. События ОбработкаПолученияДанныхВыбора, ОбработкаПолученияФормы, ОбработкаПолученияПолейПредставления, ОбработкаПолученияПредставления существуют только в модуле менеджера.
  • Служебные операции над типом. Получение пустой ссылки с дополнительной логикой, проверка дублей, начальное заполнение предопределённых данных.
  • Обновление и миграция. Процедуры заполнения данных при обновлении версии конфигурации, отложенные обработчики обновления для конкретного типа.

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

Код не использует конкретную ссылкуПодходит

Функция работает с типом в целом — переносите в модуль менеджера

Код вызывается из нескольких местПодходит

Единая точка логики устраняет дублирование

Код изменяет реквизиты объектаНе подходит

Логика экземпляра — в модуль объекта

Код управляет элементами формыНе подходит

Это зона ответственности модуля формы

Обработчики событий, доступные только в модуле менеджера

ОбработкаПолученияДанныхВыбора

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

ОбработкаПолученияФормы

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

ОбработкаПолученияПредставления и ОбработкаПолученияПолейПредставления

Эти обработчики управляют тем, как объект отображается в интерфейсе: можно заменить стандартное представление ссылки на составное (например, «Код + Наименование + Артикул»). Важно помнить: обработчики вызываются очень часто, и тяжёлый код внутри них заметно замедляет интерфейс.

Пример: функция поиска или создания элемента

Типовая задача — найти контрагента по ИНН, а если не найден — создать. Разместим функцию в модуле менеджера справочника «Контрагенты»:

Функция НайтиИлиСоздатьПоИНН(ИНН, Наименование) Экспорт

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ ПЕРВЫЕ 1

| Контрагенты.Ссылка КАК Ссылка

|ИЗ

| Справочник.Контрагенты КАК Контрагенты

|ГДЕ

| Контрагенты.ИНН = &ИНН";

Запрос.УстановитьПараметр("ИНН", ИНН);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

Возврат Выборка.Ссылка;

КонецЕсли;

НовыйЭлемент = Справочники.Контрагенты.СоздатьЭлемент();

НовыйЭлемент.Наименование = Наименование;

НовыйЭлемент.ИНН = ИНН;

НовыйЭлемент.Записать();

Возврат НовыйЭлемент.Ссылка;

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

Теперь из любого места конфигурации достаточно вызвать Справочники.Контрагенты.НайтиИлиСоздатьПоИНН(ИНН, Наименование). Логика создания существует в одном экземпляре: если потребуется добавить заполнение нового реквизита, правка делается в одном месте.

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

Модуль менеджера против общего модуля и модуля объекта

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

КритерийМодуль менеджераОбщий модульМодуль объекта
КонтекстТип в целомНет контекстаКонкретный экземпляр
Обработчики получения формы и данных выбораДоступныНедоступныНедоступны
Привязка логики к объектуЯвная, код рядом с объектомЛогика размазана по общим модулямЯвная, но только для экземпляра
Расширение функциональностиЧерез расширение модуля менеджераЧерез расширение общего модуляЧерез расширение модуля объекта
Доступ к данным объектаТолько через ссылку и запросыТолько через параметрыНапрямую через реквизиты

Модуль объекта и модуль менеджера часто путают. Правило разделения простое: всё, что можно выразить через «ЭтотОбъект», реквизиты и табличные части конкретного документа — модуль объекта. Всё, что работает со ссылками, выборками и созданием новых экземпляров — модуль менеджера.

Маршрут решения

Куда поместить код

Функция ищет, создаёт или проверяет элементы справочника или документы по условиюМодуль менеджера соответствующего объекта
Код проверяет или заполняет реквизиты конкретного записываемого объектаМодуль объекта (обработчики ПередЗаписью, ОбработкаПроверкиЗаполнения)
Код работает с разными типами объектов и не привязан к одномуОбщий модуль
Нужно изменить поведение поля ввода при подбореОбработкаПолученияДанныхВыбора в модуле менеджера

Модуль менеджера в расширениях конфигурации

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

При расширении обработчиков событий менеджера действует порядок вызова: сначала обработчик расширения, затем типовой. Для функций доступны аннотации &ИзменениеИКонтроль, &Вместо, &Перед, &После. Наиболее безопасный вариант — &ИзменениеИКонтроль: платформа проконтролирует, что расширение корректно применяется к актуальной версии типового кода при обновлении.

Типичные ошибки при работе с модулем менеджера

  • Тяжёлые запросы в обработчиках представления. Как отмечено выше, это приводит к массовым обращениям к базе при каждом отображении списка.
  • Размещение логики экземпляра. Код вида «заполнить табличную часть документа» в модуле менеджера заставляет передавать объект через параметры и усложняет отладку — ему место в модуле объекта.
  • Дублирование в общих модулях. Функция поиска элемента в общем модуле «РаботаСоСправочниками» и ещё одна в модуле формы рано или поздно расходятся в поведении.
  • Интерактивные вызовы на сервере. Модуль менеджера исполняется на сервере; попытка показать пользователю вопрос или предупреждение напрямую приведёт к ошибке. Возвращайте результат и показывайте сообщения на клиенте.
  • Забытый признак «Экспорт». Без него функция недоступна извне модуля — типичная причина ошибки «Процедура или функция с указанным именем не определена».
Типичные ошибки
01
Запрос к базе в ОбработкаПолученияПредставления — тысячи лишних обращений к СУБД и тормозящий интерфейс
02
Отсутствие слова Экспорт у функции — вызов извне невозможен, ошибка при компиляции
03
Сообщить или Вопрос в коде модуля менеджера — ошибка на сервере, сообщения нужно возвращать через параметры
04
Копипаст функции поиска в несколько модулей вместо одной функции в модуле менеджера — расхождение логики при доработках

Как проверить, что код размещён правильно

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

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

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

Вызов экспортной функции из другого модуля
Норма

Функция вызывается через Справочники.Имя.Функция() без ошибок

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

Ошибка «Процедура или функция не определена» — проверьте Экспорт и имя

Работа поля ввода с переопределённым подбором
Норма

Список подбора формируется по вашей логике и быстро

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

Заметная пауза при вводе — ищите тяжёлый запрос в обработчике

Обновление конфигурации БД
Норма

Обновление проходит, модули компилируются

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

Ошибки компиляции модуля менеджера — синтаксис или недоступный контекст

Итог

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

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

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

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

Да, если функция экспортная. На тонком и веб-клиенте вызов будет выполнен на сервере автоматически. Учитывайте, что это серверный вызов: при массовых обращениях из цикла на клиенте лучше собрать данные и сделать один вызов.

Есть ли модуль менеджера у регистров и перечислений?

Да. Модуль менеджера есть у регистров сведений, накопления, бухгалтерии и расчёта, а также у перечислений. У перечислений он чаще всего используется для обработчиков получения представления и данных выбора.

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

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

Нужно ли переносить печатные формы в модуль менеджера, если они уже в общем модуле?

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

Почему мой обработчик ОбработкаПолученияДанныхВыбора не вызывается?

Частые причины: обработчик размещён не в модуле менеджера, а в модуле формы; у поля ввода установлено свойство «АвтоОтметкаНезаполненного» или переопределён обработчик на форме; либо в параметрах обработчика не установлен признак СтандартнаяОбработка = Ложь, и платформа игнорирует вашу логику. Проверьте также, что кэш метаданных клиента обновлён.

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

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