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