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