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

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

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

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

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

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

Материал ориентирован на платформу 1С:Предприятие 8.3, однако описанные приёмы работают и в более ранних версиях 8.x, поскольку синтаксис вызова процедур не менялся.

Что нужно знать о видимости процедур перед вызовом

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

Если процедура объявлена как Процедура МояПроцедура() Экспорт, её можно вызвать извне через точку от объекта-владельца. Если слова Экспорт нет — вызов возможен только из того же модуля. Попытка вызвать неэкспортную процедуру снаружи даст ошибку компиляции или выполнения.

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

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

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

Процедура СформироватьОтчет() Экспорт

Данные = ПолучитьДанные();

ВывестиРезультат(Данные);

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

Процедура ВывестиРезультат(Данные)

Сообщить("Строк обработано: " + Данные.Количество());

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

Обратите внимание: порядок объявления процедур в модуле не важен — можно вызывать процедуру, объявленную ниже по тексту. Компилятор 1С анализирует модуль целиком. Но имя должно совпадать точно, включая регистр не обязательно, а вот русские и английские буквы различать нужно: «С» русская и «C» латинская — частая причина «невидимой» ошибки.

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

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

ОбъектОбработки = Обработки.ЗагрузкаДанных.Создать();

ОбъектОбработки.ЗаполнитьНастройки();

ОбъектОбработки.ВыполнитьЗагрузку(ПутьКФайлу);

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

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

Порядок вызова из другого модуля
  1. 1
    Откройте модуль объекта обработки и убедитесь, что процедура объявлена с ключевым словом Экспорт
  2. 2
    В вызывающем модуле создайте объект: ОбъектОбработки = Обработки.ИмяОбработки.Создать()
  3. 3
    При необходимости заполните реквизиты объекта обработки
  4. 4
    Вызовите процедуру через точку: ОбъектОбработки.ИмяПроцедуры(Параметры)
  5. 5
    Запустите код и проверьте результат по сообщениям или изменённым данным

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

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

РезультатПроверки = РаботаСКонтрагентами.ПроверитьИНН(ИНН);

Если Не РезультатПроверки Тогда

Сообщить("ИНН не прошёл проверку");

КонецЕсли;

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

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

Где размещать вызываемую процедуру

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

Когда логика относится только к этой обработке и использует её реквизиты. Требует создания объекта при внешнем вызове.

Общий модуль

Когда процедуру вызывают несколько объектов конфигурации. Не требует создания экземпляра, но нужно правильно настроить флаги клиент/сервер.

Модуль формы

Когда процедура работает с элементами формы и данными формы. Извне вызывается только через объект формы, что обычно не рекомендуется.

Вызов по имени через Выполнить и вызов с параметрами

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

ИмяПроцедуры = "ОбработатьСтроку";

Выполнить(ИмяПроцедуры + "(ПараметрыСтроки)");

У этого способа есть ограничения: строка компилируется в момент выполнения, ошибки в ней обнаруживаются только при запуске, а в безопасном режиме (например, при работе расширений) Выполнить может быть запрещён. Передавать параметры приходится через переменные, видимые в контексте выполнения, что усложняет отладку.

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

Вызов процедуры формы и обработчики событий

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

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

&НаКлиенте

Процедура ЗагрузитьФайл(Команда)

ЗагрузитьФайлНаСервере(ПутьКФайлу);

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

&НаСервере

Процедура ЗагрузитьФайлНаСервере(Путь)

ОбъектОбработки = РеквизитФормыВЗначение("Объект");

ОбъектОбработки.Загрузить(Путь);

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

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

Типичные ошибки и проверка результата

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

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

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

Типичные ошибки при вызове
01
Вызов неэкспортной процедуры из другого модуля — ошибка «не определена», лечится добавлением слова Экспорт
02
Обращение к серверному общему модулю из клиентской процедуры без флага «Вызов сервера» — ошибка компиляции
03
Изменение параметра внутри процедуры с ожиданием, что исходная переменная не изменится — параметры без Знач передаются по ссылке
04
Вызов процедуры из Выполнить с опечаткой в строке имени — ошибка проявляется только в момент выполнения
05
Серверный вызов внутри клиентского цикла — резкое падение скорости работы формы
Контрольные точки

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

Окно сообщений после выполнения
Норма

Выведены ожидаемые сообщения процедуры

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

Сообщений нет или текст ошибки компиляции/выполнения

Состояние данных
Норма

Документы, регистры или реквизиты изменились как задумано

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

Данные прежние — возможно, работа шла с копией объекта

Поведение формы
Норма

Форма обновилась, элементы доступны

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

Форма «зависает» — вероятны частые серверные вызовы

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

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

Функция возвращает значение через оператор Возврат, и её вызов можно использовать в выражении: Результат = МояФункция(Параметр). Процедура ничего не возвращает, её вызов — отдельный оператор. Если нужен результат работы, объявляйте функцию; если только действие — процедуру.

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

Да. Создайте объект через ВнешниеОбработки.Создать(ПутьКФайлу) и вызовите экспортную процедуру модуля объекта. Форма при этом не открывается. В клиент-серверном режиме может потребоваться разрешение на использование внешних обработок и отключение защиты от опасных действий для пользователя.

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

Чаще всего процедура объявлена без слова Экспорт, а вызов идёт из другого модуля. Также проверьте, не перепутаны ли русские и латинские буквы в имени, и доступен ли модуль в текущем контексте (клиент или сервер).

Как передать в процедуру таблицу значений или массив?

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

Можно ли вызвать процедуру обработки по расписанию?

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

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

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

Итог

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

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