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