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