Как в 1С 7.7 вызвать процедуру глобального модуля, если её может не быть в конфигурации?

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

При разработке универсальных внешних отчетов и обработок в платформе 1С:Предприятие 7.7 разработчики часто сталкиваются с необходимостью вызова функций или процедур из глобального модуля (например, типовой функции глПредставлениеДокумента). Если такая обработка открывается в нетиповой или другой конфигурации, где процедура отсутствует, платформа аварийно прерывает работу с ошибкой компиляции модуля.

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

Особенности компиляции и ограничения платформы 1С 7.7

Проанализируем архитектурные ограничения платформы 1С:Предприятие 7.7:

  1. Статический синтаксический контроль при загрузке: В отличие от платформы 8.x, где модуль компилируется динамически по мере выполнения блоков кода, в версии 7.7 весь модуль компилируется целиком в момент открытия формы. Если компилятор встречает прямое обращение к несуществующей функции, он немедленно выдает синтаксическую ошибку, и модуль даже не начинает выполняться. Конструкция Попытка ... Исключение в теле модуля здесь не помогает, так как ошибка возникает на этапе компиляции, а не во время исполнения.
  2. Ограничения функции Шаблон(): Попытка вызвать функцию динамически через выражение вида Шаблон("[глФункция()]") позволяет обойти ошибку компиляции основного модуля, однако при отсутствии функции платформа транслирует системную ошибку непосредственно в окно сообщений (табло), возвращая пустую строку или исходный текст, не вызывая исключительной ситуации для перехвата.
  3. Отсутствие встроенного оператора Выполнить(): Во встроенном языке 1С 7.7 штатно нет прямого аналога динамического исполнения строкового кода, как в платформе 8.x.

Способ 1. Проверка состава метаданных конфигурации

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

Посмотрим на пример кода:


Если Метаданные.Регистр("ОстаткиТМЦ").Выбран() = 1 Тогда
    // Это конфигурация Торговля и Склад, функция гарантированно есть
    СтрокаКода = "[глПредставлениеДокумента(Докум.ДокОснование)]";
    ДокументРасчета = Шаблон(СтрокаКода);
Иначе
    // Альтернативное представление для прочих конфигураций
    ДокументРасчета = Докум.ДокОснование.Вид() + " " + Докум.ДокОснование.НомерДок;
КонецЕсли;

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

Способ 2. Проверка наличия процедуры через временную внешнюю обработку

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

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

Разберем реализацию функции проверки:


Функция ЕстьПроцедураГМ(ИмяПроцедуры, КоличествоПараметров)
    Перем Путь, Имя;
    
    РасположениеФайла(Путь, Имя);
    ФС.УстТекКаталог(Путь);
    
    // Формируем список фиктивных параметров для вызова
    ТекстПараметров = "";
    Для Сч = 1 По КоличествоПараметров Цикл
        ТекстПараметров = ТекстПараметров + ?(ТекстПараметров = "", "", ",") + "1";
    КонецЦикла;
    
    // Формируем модуль, который немедленно закрывается при успехе
    ТекстОбработки = СоздатьОбъект("Текст");
    ТекстОбработки.ДобавитьСтроку("Процедура ПриОткрытии() СтатусВозврата(0); КонецПроцедуры");
    ТекстОбработки.ДобавитьСтроку(ИмяПроцедуры + "(" + ТекстПараметров + ");");
    
    ИмяФайла = Путь + "CheckProc.txt";
    ТекстОбработки.Записать(ИмяФайла);
    
    // Пытаемся открыть проверочную обработку (использующую директиву #ЗагрузитьИзФайла)
    Попытка
        ОткрытьФорму("Отчет",, Путь + "CheckProc.ert");
        Возврат 1; // Процедура успешно скомпилировалась и существует
    Исключение
        Возврат 0; // Процедуры нет в конфигурации
    КонецПопытки;
КонецФункции

При использовании этого приема форма отчета CheckProc.ert сразу отменяет свое открытие через СтатусВозврата(0), пользователь не видит мерцания окон, а результат проверки позволяет безопасно решить, какой алгоритм запускать далее.

Способ 3. Использование внешней компоненты 1С++ (модуль ВыполняемыйМодуль)

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

Проанализируем пример перехвата компиляции с помощью объекта ВыполняемыйМодуль:


Модуль = СоздатьОбъект("ВыполняемыйМодуль");
Модуль.УстановитьМодуль("Рез = глПредставлениеДокумента(КонтекстДокумента);");

Попытка
    Модуль.КомпилироватьМодуль();
    Модуль.ВыполнитьМодуль();
Исключение
    // Процедура отсутствует — выполняем локальный альтернативный алгоритм
    Сообщить("Глобальная функция не найдена, используется локальный расчет", "I");
КонецПопытки;

Метод КомпилироватьМодуль() генерирует штатное перехватываемое исключение, если вызываемая процедура не найдена в таблице глобальных символов программы, что позволяет легко управлять потоком выполнения.

Способ 4. Проверка через OLE Automation (EvalExpr)

Еще один вариант валидации без применения внешних библиотек — использование OLE-соединения с текущей информационной базой через объект V77.Application. При вычислении выражения через EvalExpr обращение к отсутствующей функции генерирует COM-ошибку, которая корректно перехватывается блоком Попытка ... Исключение и не засоряет интерактивное окно сообщений пользователя.

Итоги

Для создания универсальных обработок в 1С 7.7 оптимально использовать комбинацию методов:

  1. Если состав конфигураций известен заранее — используем проверку уникальных объектов через коллекцию Метаданные.
  2. Если конфигурации произвольные и сторонние компоненты запрещены — используем проверку через создание временного модуля с отменой открытия.
  3. Если в базе подключена 1С++ — используем класс ВыполняемыйМодуль.
← На главную