Как вызвать процедуру глобального модуля по имени из переменной в 1С 7.7

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

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

Проблема контекста и метод ВыполнитьПроцедуру в FormEx

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

Проблема в том, что «Глобальный контекст» в 1С 7.7 не является объектом, который можно легко передать в параметре. Поэтому попытка выполнить код:


Сервис = СоздатьОбъект("Сервис");
ПутьОбработчика = "МояГлобальнаяПроцедура";
Сервис.ВыполнитьПроцедуру( , ПутьОбработчика);

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

Решение №1: Использование компоненты 1С++ и объекта ВыполняемыйМодуль

Если в вашей конфигурации используется мощная библиотека 1С++, то наиболее правильным и профессиональным способом будет использование класса ВыполняемыйМодуль. Этот объект позволяет компилировать и исполнять произвольный код на языке 1С прямо во время работы программы.

Разберем алгоритм работы с этим объектом по шагам:

  1. Создаем экземпляр объекта ВыполняемыйМодуль.
  2. Формируем текст модуля, который содержит вызов нашей процедуры.
  3. Компилируем и выполняем этот код.

Пример кода будет выглядеть следующим образом:


// Предположим, ИмяПроц - это переменная со строкой "ГлОбработкаДанных"
ВМ = СоздатьОбъект("ВыполняемыйМодуль");
ТекстКода = ИмяПроц + "();"; // Формируем строку вызова
ВМ.УстановитьМодуль(ТекстКода);
ВМ.КомпилироватьИВыполнитьМодуль();

Преимущество этого метода заключается в том, что динамически скомпилированный код исполняется в окружении, где доступны все экспортные функции и процедуры глобального модуля. Это максимально приближает нас к функционалу Выполнить() из 1С 8.3.

Решение №2: Использование штатной функции Шаблон

Если вы не хотите или не можете подключать тяжелые внешние компоненты, можно воспользоваться «хитростью» со встроенной функцией Шаблон(). Эта функция предназначена для вычисления выражений внутри строк, но программисты 7.7 давно используют ее для динамического вызова кода.

Важное ограничение: функция Шаблон() умеет вызывать только функции. Попытка вызвать процедуру приведет к ошибке: «Процедура вызывается как функция».

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

В Глобальном модуле прописываем:


Функция глВыполнитьЭкспортнуюПроцедуру(ИмяПроцедуры) Экспорт
    // Здесь мы используем Шаблон для вызова, 
    // но вызываемая процедура сама должна быть функцией
    Возврат Шаблон("[" + ИмяПроцедуры + "()]");
КонецФункции

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

Однако автор темы предложил более изящный вариант: вызывать через Шаблон() одну общую функцию, которая внутри себя уже знает, что делать. Если вы планируете динамически вызывать много разных процедур, лучше всего заранее оформить их как функции, возвращающие 0 или 1.

Решение №3: Метод с динамическим созданием внешней обработки

Существует еще один «экзотический», но надежный способ, который работает вообще без внешних компонент и ограничений функции Шаблон(). Мы можем программно создать текстовый файл с расширением .ert, который будет являться внешней обработкой, и запустить его.

Рассмотрим логику процесса:

  1. Генерируем текст модуля обработки, где в процедуре ПриОткрытии() прописан вызов нужной нам глобальной процедуры.
  2. Записываем этот текст в файл на диск.
  3. Вызываем ОткрытьФорму("Отчет", , ПутьКФайлу);.

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

Подведем итоги

Выясним, какой метод лучше выбрать в зависимости от ситуации:

Помните, что динамический вызов кода — это мощный инструмент, который требует внимательности при отладке, так как синтаксические ошибки в именах процедур будут обнаружены только в момент выполнения программы (Runtime), а не при сохранении конфигурации.

← На главную