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