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

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

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

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

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

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

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

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

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

Объявление экспортной функции выглядит так:

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

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

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

Ключевое слово Экспорт ставится после списка параметров, перед телом функции. Если его забыть, при попытке вызова из другого модуля конфигуратор выдаст ошибку «Процедура или функция с указанным именем не определена». Это самая частая причина, почему «не видно» функцию.

Вызов функции из общего модуля

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

// Вызов из модуля формы документа

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

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

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

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

Настройка флагов общего модуля: Сервер, Клиент, Вызов сервера

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

ФлагЧто означаетКогда ставить
СерверМодуль компилируется на сервереЗапросы к БД, работа с объектами, проведение
Клиент (управляемое приложение)Код доступен на тонком клиентеИнтерфейсная логика, диалоги, предупреждения
Клиент (обычное приложение)Код доступен в толстом клиенте обычного приложенияТолько для конфигураций на обычных формах
Вызов сервераРазрешает вызывать серверный модуль с клиентаКогда клиентскому коду нужны серверные данные
Привилегированный режимКод выполняется без проверки правОперации, которые должны работать у любого пользователя

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

Флаг «Привилегированный режим» влияет не на видимость, а на права: код внутри модуля выполняется без проверки RLS и прав доступа. Ставьте его осознанно — ошибка здесь может открыть пользователям доступ к данным, которые им видеть не положено.

Вызов функции из модуля объекта и модуля менеджера

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

ДокументОбъект = ДокументСсылка.ПолучитьОбъект();

Результат = ДокументОбъект.ПроверитьЗаполнениеТабличнойЧасти();

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

Модуль менеджера объекта вызывается проще — через менеджер типа:

Сумма = Документы.РеализацияТоваровУслуг.ПолучитьСуммуДокумента(СсылкаНаДокумент);

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

Сравнение вариантов

Общий модуль

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

Модуль менеджера

Серверные функции, относящиеся к типу объекта в целом: получение данных, расчёты по ссылке. Не требует ПолучитьОбъект(), работает быстрее.

Модуль объекта

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

Вызов функции между формами и из модуля команды

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

Если всё же нужно вызвать функцию открытой формы, используется механизм оповещений:

// В форме-источнике

Оповестить("ЗапроситьДанные", ПараметрыОповещения, ЭтотОбъект);

// В форме-приёмнике — обработчик ОбработкаОповещения

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

Директивы компиляции и контекст выполнения

В управляемом приложении один и тот же модуль формы компилируется на клиенте и на сервере, поэтому каждая процедура помечается директивой. От директивы зависит, какие вызовы разрешены:

  • &НаКлиенте — доступны клиентские общие модули и серверные модули с флагом «Вызов сервера»;
  • &НаСервере — доступны серверные общие модули, менеджеры объектов, запросы;
  • &НаСервереБезКонтекста — то же, что на сервере, но без доступа к данным формы; такие процедуры выполняются быстрее;
  • &НаКлиентеНаСервереБезКонтекста — только в модулях форм с осторожностью; обычно такой код выносят в общий модуль с обоими флагами.

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

&НаКлиенте

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

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

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

&НаСервере

Процедура ПересчитатьИтогиНаСервере()

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

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

Типичные ошибки и их устранение

Большинство проблем при межмодульных вызовах диагностируется по тексту ошибки конфигуратора. Проверку удобно запускать через «Конфигурация → Проверка конфигурации» с включённой проверкой логической целостности.

Типичные ошибки
01
Забыто ключевое слово Экспорт — ошибка «Процедура или функция с указанным именем не определена» при вызове из другого модуля
02
Вызов серверного модуля из клиентского контекста без флага «Вызов сервера» — ошибка компиляции в модуле формы
03
Опечатка в имени модуля или функции — та же ошибка «не определена»; используйте Ctrl+Пробел для подстановки имён
04
Циклические зависимости: модуль А вызывает модуль Б, а модуль Б — модуль А. На клиенте это может приводить к ошибкам инициализации; выносите общий код в третий модуль
05
Ожидание возвращаемого значения от процедуры — в 1С процедура не возвращает значение, нужна именно Функция с оператором Возврат

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

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

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

Проверка конфигурации
Норма

Ошибок компиляции модулей нет

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

Сообщения «не определена» или «модуль не обнаружен»

Запуск вызова в режиме предприятия
Норма

Функция возвращает ожидаемое значение

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

Исключение в момент вызова или пустой результат

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

Вызов выполняется на нужной стороне (клиент/сервер) без лишних серверных вызовов

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

Каждое обращение из цикла идёт на сервер — заметные тормоза интерфейса

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

Удобный приём при разработке: ставьте точку останова на первой строке вызываемой функции и запускайте отладку. Если отладчик туда не попадает, значит, проблема в видимости или контексте, а не в логике самой функции. Это сразу сужает поиск вдвое.
ПЗ
Практическое замечание

FAQ: частые вопросы о вызове функций между модулями

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

Да, общие модули могут вызывать друг друга без ограничений, если оба доступны в одном контексте (например, оба серверные). Следите только за циклическими зависимостями: если модуль А вызывает Б, а Б вызывает А, это может привести к ошибкам инициализации, особенно на клиенте. Выносите общую часть в третий модуль.

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

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

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

В объявлении функции параметр помечается словом Знач, если передаётся по значению. Если Знач не указано, параметр передаётся по ссылке, и изменения внутри функции будут видны снаружи. Для структур и массивов передача по ссылке работает всегда, так как это ссылочные типы.

Чем вызов функции отличается от вызова процедуры из другого модуля?

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

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

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

Итог

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

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