Как в 1С вызвать функцию или процедуру, если её имя находится в переменной?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике разработки на платформе «1С:Предприятие 8» нередко возникают ситуации, когда имя вызываемого метода (функции или процедуры) становится известным только в момент выполнения кода. Это может быть связано с построением универсальных механизмов, обработок или при разработке гибких систем плагинов. Рассмотрим подробно, как реализовать такой вызов, какие инструменты предоставляет платформа и каких ошибок следует избегать.

Метод 1: Использование функции Вычислить()

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

Проанализируем пример кода:


// Имя функции, которую нужно вызвать
ИмяФункции = "РассчитатьСуммуДокумента";

// Параметр, который мы передаем
ТекущаяСсылка = Документы.РеализацияТоваровУслуг.НайтиПоНомеру("001");

// Формируем строку вызова и получаем результат
Результат = Вычислить(ИмяФункции + "(ТекущаяСсылка)");

Обратим внимание на важный нюанс: в строке, которую мы передаем в Вычислить(), должны фигурировать имена переменных, которые доступны в текущем контексте. Платформа не сможет «прочитать» значение ссылки, если мы просто попытаемся преобразовать её в строку. Мы передаем именно имя переменной ТекущаяСсылка внутрь строки вызова.

Метод 2: Использование оператора Выполнить()

В случаях, когда нам нужно вызвать процедуру (метод, который не возвращает значение), используется оператор Выполнить(). Он исполняет фрагмент кода, переданный ему в виде строки.

Разберем, как это работает на практике:


ИмяПроцедуры = "ОбщегоНазначения.ВывестиСообщениеПользователю";
ТекстСообщения = "Действие выполнено успешно!";

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

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

Метод 3: Использование ОписаниеОповещения (современный подход)

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

Рассмотрим этот механизм подробнее:

  1. Создаем объект ОписаниеОповещения, указывая имя процедуры и модуль.
  2. Используем метод ВыполнитьОбработкуОповещения().

// Подготавливаем описание вызова
Оповещение = Новый ОписаниеОповещения("ИмяВашейПроцедуры", ЭтотОбъект);

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

// Осуществляем вызов
ВыполнитьОбработкуОповещения(Оповещение, ПараметрыВызова);

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

Метод 4: Создание управляющей функции (Диспетчера)

Иногда использование Вычислить() или Выполнить() запрещено корпоративными стандартами разработки из-за потенциальных уязвимостей (так называемых инъекций кода). В этом случае проанализируем альтернативный вариант — создание функции-диспетчера.

Выясним, как это выглядит в коде:


Функция ВызватьМетодДинамически(ИмяМетода, Параметр)
    
    Если ИмяМетода = "РасчитатьСкидку" Тогда
        Возврат РасчитатьСкидку(Параметр);
    ИначеЕсли ИмяМетода = "ОпределитьНалог" Тогда
        Возврат ОпределитьНалог(Параметр);
    Иначе
        ВызватьИсключение "Метод не найден!";
    КонецЕсли;
    
КонецФункции

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

Безопасность и производительность

При работе с динамическим исполнением кода важно учитывать несколько критических факторов:

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

← На главную