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

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

Как вызвать процедуру из другой процедуры в 1С

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

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

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

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

Вызов процедуры внутри того же модуля

Простейший случай — обе процедуры находятся в одном модуле (модуле формы, модуля объекта или общем модуле). Вызов выполняется по имени с указанием параметров в круглых скобках. Если параметров нет, скобки всё равно ставятся.

Процедура ОбработатьДокумент(ДокументСсылка)

Сообщить("Начало обработки");

ПроверитьЗаполнение(ДокументСсылка);

ЗаписатьДокумент(ДокументСсылка);

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

Процедура ПроверитьЗаполнение(ДокументСсылка)

// логика проверки

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

Порядок объявления процедур в модуле не важен: вызываемая процедура может быть описана ниже по тексту. Компилятор 1С сначала собирает все объявления модуля, а потом выполняет код. Однако для читаемости принято размещать вспомогательные процедуры после основных или выносить их в отдельную область #Область СлужебныеПроцедурыИФункции.

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

Вызов процедуры из общего модуля

Общие модули — стандартное место для переиспользуемого кода. Чтобы процедура общего модуля была доступна извне, она обязательно объявляется с ключевым словом Экспорт:

// Общий модуль РаботаСДокументами

Процедура ПровестиДокумент(ДокументСсылка) Экспорт

// логика проведения

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

Вызов из любого другого модуля выполняется через имя общего модуля и точку:

РаботаСДокументами.ПровестиДокумент(МояСсылка);

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

Вызов с директивами компиляции: &НаСервере, &НаКлиенте

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

&НаКлиенте

Процедура КомандаОбработать(Команда)

ОбработатьНаСервере(Элементы.Список.ТекущаяСтрока);

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

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

Процедура ОбработатьНаСервере(Ссылка)

РаботаСДокументами.ПровестиДокумент(Ссылка);

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

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

Передача параметров и получение результата

Параметры передаются в вызываемую процедуру через запятую. По умолчанию параметры передаются по ссылке: если вызываемая процедура изменит значение параметра, изменение будет видно в вызывающем коде. Чтобы запретить изменение, параметр объявляется с ключевым словом Знач.

Процедура РассчитатьСкидку(Знач Сумма, Скидка) Экспорт

// Сумма изменить нельзя, Скидка — можно, и она вернётся вызывающему коду

Скидка = Сумма * 0.1;

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

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

СуммаСкидки = РаботаСДокументами.РассчитатьСкидку(СуммаДокумента);

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

bsl
// Объявление в общем модуле
Функция ПолучитьКурс(Валюта, Дата) Экспорт
    Возврат РегистрыСведений.КурсыВалют.ПолучитьПоследнее(Дата, Новый Структура("Валюта", Валюта)).Курс;
КонецФункции

// Вызов из другой процедуры
Курс = РаботаСВалютами.ПолучитьКурс(ВалютаДокумента, ДатаДокумента);

Вызов процедуры по имени: Выполнить и ОписаниеОповещения

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

Выполнить("ОбработатьСтроку_" + ВидОперации + "(СтрокаДанных)");

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

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

Как проверить, что вызов работает

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

Второй уровень — отладка. Поставьте точку останова на строке вызова (F9) и запустите отладку (F5). Шаг «Войти» (F11) перенесёт выполнение внутрь вызываемой процедуры, шаг «Перешагнуть» (F10) выполнит её без входа. Так вы убедитесь, что вызов происходит, параметры передаются с ожидаемыми значениями, а код внутри выполняется корректно.

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

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

Синтаксическая проверка модуля
Норма

Ошибок нет, вызов распознан

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

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

Отладка с точкой останова
Норма

F11 переносит выполнение внутрь вызываемой процедуры

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

Выполнение не заходит в процедуру или падает с ошибкой

Значения параметров
Норма

В табло видны ожидаемые значения на входе

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

Параметры равны Неопределено или имеют другой тип

Итог

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

Внутри модуля процедура вызывается по имени, из общего модуля — через ИмяМодуля.ИмяПроцедуры() с обязательным Экспорт. Следите за контекстом исполнения (клиент/сервер), числом параметров и минимизируйте серверные вызовы. Проверяйте вызов синтаксическим контролем и отладкой.

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

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

Проверьте три вещи: написано ли имя без опечаток, добавлено ли ключевое слово Экспорт у процедуры в общем модуле и совпадает ли контекст исполнения (серверный модуль не виден на клиенте). Чаще всего причина — отсутствующий Экспорт.

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

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

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

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

Как вызвать процедуру из расширения конфигурации?

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

Безопасно ли использовать Выполнить для вызова процедур?

Только когда имя формируется из доверенных внутренних данных и нет другого способа. Строка для Выполнить не проверяется компилятором, ошибки проявляются в рантайме, а при использовании пользовательского ввода возникает риск выполнения произвольного кода.