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

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

Как вызвать функцию из общего модуля в 1С

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

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

Главные условия успешного вызова — экспортная функция (ключевое слово Экспорт после объявления) и корректно выставленные флаги контекста исполнения модуля: «Сервер», «Клиент (обычное приложение)», «Клиент (управляемое приложение)», «Внешнее соединение». Если контекст вызова не совпадает с контекстом модуля, вы получите ошибку «Процедура или функция с указанным именем не определена».

Ниже разобраны пошаговая настройка модуля, синтаксис вызова с клиента и с сервера, передача параметров, работа с возвращаемым значением, а также типичные ошибки и способы их диагностики.

Что такое общий модуль и когда выносить в него функции

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

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

Общие модули принято группировать по смыслу и называть с суффиксами, отражающими контекст: РаботаСоСтроками, РасчетыСервер, ИнтерфейсКлиент. Суффиксы «Сервер», «Клиент», «ВызовСервера» помогают сразу понять, где исполняется код, и избежать ошибок с контекстом.

Как подготовить общий модуль к вызову

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

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

Функция РассчитатьСуммуСНДС(Сумма, СтавкаНДС) Экспорт

Если СтавкаНДС = 0 Тогда

Возврат Сумма;

КонецЕсли;

Возврат Сумма + Сумма * СтавкаНДС / 100;

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

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

Порядок действий
  1. 1
    Создайте общий модуль: Конфигурация → Общие → Общие модули → Добавить
  2. 2
    В свойствах модуля включите нужные флаги контекста (Сервер и/или Клиент)
  3. 3
    Напишите функцию с ключевым словом Экспорт
  4. 4
    Сохраните конфигурацию и обновите конфигурацию базы данных (F7)
  5. 5
    Вызовите функцию по схеме ИмяМодуля.ИмяФункции(Параметры) и проверьте результат

Синтаксис вызова функции

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

// Присвоение результата переменной

ИтоговаяСумма = РасчетыСервер.РассчитатьСуммуСНДС(10000, 20);

// Использование в выражении

Если РасчетыСервер.РассчитатьСуммуСНДС(СуммаДокумента, 20) > Лимит Тогда

Сообщить("Превышен лимит");

КонецЕсли;

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

Если у функции есть параметры со значениями по умолчанию (Параметр = Неопределено), необязательные параметры можно опускать, но пропускать параметр в середине списка нельзя — можно только не указывать хвостовые.

bsl
Результат = РасчетыСервер.РассчитатьСуммуСНДС(СуммаДокумента, 20);

Вызов с клиента и с сервера: в чём разница

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

Вызов серверной функции из клиентского обработчика

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

&НаКлиенте

Процедура Пересчитать(Команда)

Итог = ПересчитатьНаСервере(Сумма);

КонецПроцедуры

&НаСервереБезКонтекста

Функция ПересчитатьНаСервере(Сумма)

Возврат РасчетыСервер.РассчитатьСуммуСНДС(Сумма, 20);

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

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

Варианты вызова серверной логики с клиента

Серверный метод формы

Подходит для логики конкретной формы; один вызов — один серверный контекст, можно передать данные формы

Модуль с флагом «Вызов сервера»

Подходит для универсальных функций без привязки к форме; каждый вызов — отдельный серверный вызов, нельзя передавать данные формы

Клиентский общий модуль

Подходит, если логика может выполняться на клиенте и не требует запросов к базе данных

Проверка результата и отладка вызова

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

Для пошаговой отладки поставьте точку останова внутри функции общего модуля и запустите отладку (F5). Если точка не срабатывает, значит, вызов либо не доходит до функции, либо исполняется в другом контексте (например, серверный код при отладке только клиентского сеанса). Включите в настройках отладки нужные типы подключений.

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

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

Компиляция модуля
Норма

Синтакс-контроль проходит без ошибок, функция видна в подсказке после точки

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

Ошибка «Процедура или функция с указанным именем не определена»

Возвращаемое значение
Норма

На контрольных данных результат совпадает с ожидаемым

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

Возвращается Неопределено или неверное значение

Контекст исполнения
Норма

Вызов из клиентского кода идёт в клиентский модуль, из серверного — в серверный

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

Клиентский код пытается вызвать серверный модуль напрямую

Граничные случаи
Норма

Пустые и нулевые параметры обрабатываются без исключений

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

Ошибка при Неопределено или пустой ссылке

Типичные ошибки и ограничения

Самая частая ошибка — «Процедура или функция с указанным именем не определена». Причины: забыто слово Экспорт, опечатка в имени модуля или функции, либо контекст вызова не совпадает с флагами модуля. Проверяйте в этом порядке: сначала Экспорт, затем имя, затем флаги.

Вторая группа проблем — производительность. Клиент-серверные вызовы в цикле (например, обращение к серверному общему модулю при обходе тысячи строк таблицы) резко замедляют работу. Решение — вынести весь цикл на сервер и вызывать его один раз, передав массив или таблицу значений.

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

Типичные ошибки
01
Нет слова Экспорт у функции — вызов извне приводит к ошибке «не определена»
02
Вызов серверного модуля из клиентского кода напрямую — ошибка компиляции управляемой формы
03
Включён флаг «Вызов сервера» у модуля без реальной необходимости — лишняя точка обхода безопасности и путаница в архитектуре
04
Серверный вызов внутри цикла по строкам — многократные обращения к серверу и резкое падение скорости
05
Изменение параметра, переданного без Знач, — неожиданное изменение переменной в вызывающем коде

Когда выбрать другой подход

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

Для кода, завязанного на форму, подходят команды формы и серверные процедуры формы. Для интеграционных сценариев, где нужен доступ извне, рассмотрите HTTP-сервисы вместо общих модулей. Общий модуль остаётся оптимальным выбором именно для прикладной логики, общей для нескольких объектов конфигурации.

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

Как выбрать место для функции

Функция нужна нескольким документам и справочникамОбщий модуль с соответствующим контекстом
Логика относится только к одному виду объектовМодуль менеджера или модуль объекта
Код работает с данными конкретной формыСерверная процедура формы
Функцию нужно вызывать из внешних системHTTP-сервис, а не общий модуль

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

Можно ли вызвать функцию общего модуля из модуля объекта документа?

Да. Модуль объекта исполняется на сервере, поэтому из него доступны серверные общие модули и клиент-серверные модули с флагом «Сервер». Вызов стандартный: ИмяМодуля.ИмяФункции(Параметры).

Почему функция видна в конфигураторе, но в режиме предприятия возникает ошибка «не определена»?

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

Можно ли вызвать функцию без Экспорта?

Только из того же общего модуля. Без ключевого слова Экспорт функция является приватной и недоступна извне — это осознанный способ скрыть вспомогательные функции.

Как передать в серверную функцию данные формы?

Напрямую объект ДанныеФормы в общий модуль передавать нельзя. Преобразуйте данные в серверный объект через РеквизитФормыВЗначение() в серверной процедуре формы и передайте полученный объект, либо передавайте отдельные примитивные значения и ссылки.

Что делает настройка «Повторное использование возвращаемых значений»?

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

Можно ли вызвать функцию общего модуля из внешней обработки?

Да, если обработка работает в той же информационной базе: общие модули конфигурации доступны из модулей внешних обработок по тем же правилам контекста. Серверные модули — из серверного кода обработки, клиентские — из клиентского.

Итог

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

Вызов функции из общего модуля — это ИмяМодуля.ИмяФункции(Параметры). Три условия успеха: слово Экспорт у функции, правильные флаги контекста модуля и соответствие места вызова этому контексту. Серверную логику из клиентского кода вызывайте через серверный метод формы или модуль с флагом «Вызов сервера», избегая вызовов в циклах.