Разработка и Конфигурация · 9 мин
Как вызвать процедуру из другой процедуры в 1С
Как вызвать процедуру из другой процедуры в 1С: синтаксис вызова, Экспорт, общие модули, передача параметров, типичные ошибки и проверка результата.
Вызов одной процедуры из другой — базовый приём структурирования кода на встроенном языке 1С. Он позволяет не дублировать логику, выносить повторяющиеся операции в отдельные блоки и делать модули читаемыми. Синтаксис вызова зависит от того, где находится вызываемая процедура: в том же модуле, в общем модуле или в модуле другого объекта.
Главное правило: процедура, расположенная в том же модуле, вызывается просто по имени. Процедура из другого модуля доступна только если она объявлена с ключевым словом Экспорт, а сам модуль настроен соответствующим образом (например, общий модуль с флагом «Сервер» для серверного вызова). Нарушение этих условий — самая частая причина ошибки «Процедура или функция с указанным именем не определена».
Ниже разобраны все типовые сценарии: вызов внутри модуля, вызов из общего модуля, передача параметров, работа с возвращаемыми значениями через функции, а также типичные ошибки и способы их диагностики.
Вызов процедуры внутри того же модуля
Простейший случай — обе процедуры находятся в одном модуле (модуле формы, модуля объекта или общем модуле). Вызов выполняется по имени с указанием параметров в круглых скобках. Если параметров нет, скобки всё равно ставятся.
Процедура ОбработатьДокумент(ДокументСсылка)
Сообщить("Начало обработки");
ПроверитьЗаполнение(ДокументСсылка);
ЗаписатьДокумент(ДокументСсылка);
КонецПроцедуры
Процедура ПроверитьЗаполнение(ДокументСсылка)
// логика проверки
КонецПроцедуры
Порядок объявления процедур в модуле не важен: вызываемая процедура может быть описана ниже по тексту. Компилятор 1С сначала собирает все объявления модуля, а потом выполняет код. Однако для читаемости принято размещать вспомогательные процедуры после основных или выносить их в отдельную область #Область СлужебныеПроцедурыИФункции.
Если вызываемая процедура не нужна снаружи модуля, не добавляйте к ней Экспорт. Это сокращает «публичный интерфейс» модуля и защищает от случайных вызовов извне, которые могут нарушить внутреннюю логику.
Вызов процедуры из общего модуля
Общие модули — стандартное место для переиспользуемого кода. Чтобы процедура общего модуля была доступна извне, она обязательно объявляется с ключевым словом Экспорт:
// Общий модуль РаботаСДокументами
Процедура ПровестиДокумент(ДокументСсылка) Экспорт
// логика проведения
КонецПроцедуры
Вызов из любого другого модуля выполняется через имя общего модуля и точку:
РаботаСДокументами.ПровестиДокумент(МояСсылка);
Обратите внимание на контекст исполнения. Если общий модуль имеет только флаг «Сервер», его процедуры недоступны на клиенте. Если код вызывается из клиентской процедуры формы, а модуль серверный — платформа выдаст ошибку. Для клиентского кода используются модули с флагами «Клиент (обычное приложение)» или «Клиент (управляемое приложение)», для универсального — сочетание флагов.
Вызов с директивами компиляции: &НаСервере, &НаКлиенте
В модулях форм процедуры разграничиваются директивами компиляции. Процедура с директивой &НаКлиенте не может напрямую вызвать процедуру &НаСервере в обычном порядке — точнее, может, но такой вызов означает обращение к серверу, и он должен быть осознанным. Процедура &НаСервереБезКонтекста вообще не видит данные формы и вызывается как статическая.
&НаКлиенте
Процедура КомандаОбработать(Команда)
ОбработатьНаСервере(Элементы.Список.ТекущаяСтрока);
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ОбработатьНаСервере(Ссылка)
РаботаСДокументами.ПровестиДокумент(Ссылка);
КонецПроцедуры
Практическое правило: клиентская процедура собирает данные и отдаёт команду, серверная выполняет работу с базой. Процедуры &НаСервереБезКонтекста предпочтительнее, когда данные формы не нужны, — они работают быстрее, так как не сериализуют форму.
Передача параметров и получение результата
Параметры передаются в вызываемую процедуру через запятую. По умолчанию параметры передаются по ссылке: если вызываемая процедура изменит значение параметра, изменение будет видно в вызывающем коде. Чтобы запретить изменение, параметр объявляется с ключевым словом Знач.
Процедура РассчитатьСкидку(Знач Сумма, Скидка) Экспорт
// Сумма изменить нельзя, Скидка — можно, и она вернётся вызывающему коду
Скидка = Сумма * 0.1;
КонецПроцедуры
Если нужно вернуть результат, чаще правильнее использовать функцию вместо процедуры с «выходным» параметром. Функция вызывается так же, но возвращает значение через Возврат:
СуммаСкидки = РаботаСДокументами.РассчитатьСкидку(СуммаДокумента);
Число и порядок фактических параметров при вызове должны соответствовать объявлению. Параметры со значениями по умолчанию (Параметр = Неопределено) можно опускать, но только если они идут в конце списка либо вы явно пропускаете их запятыми.
// Объявление в общем модуле
Функция ПолучитьКурс(Валюта, Дата) Экспорт
Возврат РегистрыСведений.КурсыВалют.ПолучитьПоследнее(Дата, Новый Структура("Валюта", Валюта)).Курс;
КонецФункции
// Вызов из другой процедуры
Курс = РаботаСВалютами.ПолучитьКурс(ВалютаДокумента, ДатаДокумента);Вызов процедуры по имени: Выполнить и ОписаниеОповещения
Иногда имя вызываемой процедуры известно только во время выполнения — например, оно хранится в настройках. Для таких случаев существует оператор Выполнить, которому передаётся строка с кодом вызова. Это мощный, но рискованный инструмент: ошибки в строке обнаруживаются только в момент выполнения, а не при проверке модуля.
Выполнить("ОбработатьСтроку_" + ВидОперации + "(СтрокаДанных)");
Для асинхронных сценариев (после вопроса пользователю, после выбора файла) используется ОписаниеОповещения: указывается имя процедуры-обработчика, которая будет вызвана по завершении действия. Процедура-обработчик должна находиться в том же модуле формы и иметь строго определённый набор параметров — первым всегда идёт результат, последним — дополнительные параметры.
Как проверить, что вызов работает
Первый уровень проверки — синтаксический контроль модуля: в конфигураторе откройте модуль и выполните «Конфигурация → Проверка конфигурации» либо проверку модуля через контекстное меню. Ошибки несуществующих имён и неверного числа параметров выявляются уже на этом этапе.
Второй уровень — отладка. Поставьте точку останова на строке вызова (F9) и запустите отладку (F5). Шаг «Войти» (F11) перенесёт выполнение внутрь вызываемой процедуры, шаг «Перешагнуть» (F10) выполнит её без входа. Так вы убедитесь, что вызов происходит, параметры передаются с ожидаемыми значениями, а код внутри выполняется корректно.
Как проверить результат
Ошибок нет, вызов распознан
«Процедура или функция с указанным именем не определена»
F11 переносит выполнение внутрь вызываемой процедуры
Выполнение не заходит в процедуру или падает с ошибкой
В табло видны ожидаемые значения на входе
Параметры равны Неопределено или имеют другой тип
Что важно запомнить
Внутри модуля процедура вызывается по имени, из общего модуля — через ИмяМодуля.ИмяПроцедуры() с обязательным Экспорт. Следите за контекстом исполнения (клиент/сервер), числом параметров и минимизируйте серверные вызовы. Проверяйте вызов синтаксическим контролем и отладкой.
Частые вопросы
Что делать, если возникает ошибка «Процедура или функция с указанным именем не определена»?
Проверьте три вещи: написано ли имя без опечаток, добавлено ли ключевое слово Экспорт у процедуры в общем модуле и совпадает ли контекст исполнения (серверный модуль не виден на клиенте). Чаще всего причина — отсутствующий Экспорт.
Можно ли вызвать процедуру модуля объекта из другого объекта?
Да, но только через сам объект: сначала получите объект методом ПолучитьОбъект() по ссылке, затем вызовите его экспортную процедуру. Учтите, что ПолучитьОбъект() создаёт объект в памяти — это ресурсозатратная операция, поэтому часто логику выносят в общий модуль.
Чем вызов функции отличается от вызова процедуры?
Синтаксис вызова одинаковый, но функция возвращает значение через оператор Возврат, и её вызов можно использовать в выражениях и присваиваниях. Процедуру в выражение подставить нельзя — это синтаксическая ошибка.
Как вызвать процедуру из расширения конфигурации?
Из расширения можно вызывать экспортные процедуры общих модулей основной конфигурации обычным способом. Обратный вызов — из основной конфигурации в модуль расширения — напрямую невозможен, так как основная конфигурация не знает о расширении.
Безопасно ли использовать Выполнить для вызова процедур?
Только когда имя формируется из доверенных внутренних данных и нет другого способа. Строка для Выполнить не проверяется компилятором, ошибки проявляются в рантайме, а при использовании пользовательского ввода возникает риск выполнения произвольного кода.