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

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

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

Программная проверка с помощью динамического вычисления

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

Рассмотрим подробнее способ с использованием функции Вычислить() внутри блока перехвата исключений. Это предотвратит падение компилятора:


Перем_Существует = Ложь;
Попытка
    Значение = Вычислить("ИмяИскомойГлобальнойПеременной");
    Перем_Существует = Истина;
    Сообщить("Переменная существует!");
Исключение
    Сообщить("Переменной нет или она недоступна (не экспортная).");
КонецПопытки;

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

Поиск имен в выгруженных файлах конфигурации

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

  1. Выгружаем конфигурацию в файлы через конфигуратор.
  2. Даже закрытые модули выгружаются в каталоги, но не с привычным расширением исходного кода, а в виде бинарных файлов Module.bin.
  3. Открываем эти файлы или осуществляем по ним полнотекстовый поиск в кодировке UTF-8.
  4. Внутри файлов, как правило, присутствуют все используемые локальные и глобальные имена в открытом виде (если только не применялась глубокая обфускация сторонними средствами защиты, но глобальные имена обычно не обфусцируют).

Проблема кэширования драйверов торгового оборудования

Зачастую поиск глобальных переменных связан с попыткой оптимизировать работу оборудования (например, онлайн-касс ККТ). Выясним причину на практическом примере: при каждом обращении к кассе происходит ее подключение, загрузка драйвера, создание объекта драйвера и получение ID. Это может занимать около 3 секунд. Если объект драйвера хранится в локальной переменной внешней обработки, он уничтожается при каждом закрытии этой обработки.

Возникает желание сохранить COM-объект в параметрах сеанса или глобальной переменной. Однако платформа 1С имеет строгие ограничения: внешние компоненты (Native API) и COM-объекты драйверов хранятся исключительно в адресном пространстве клиентского приложения как указатели на неуправляемые ресурсы. Их физически невозможно сериализовать и сохранить в параметрах сеанса или регистрах сведений.

Альтернативные способы сохранения объекта драйвера без правки закрытых модулей

Посмотрим на штатные способы кэширования объекта в памяти сеанса, если глобальная переменная недоступна или отсутствует в закрытой конфигурации:

  1. Кэширование через служебную невидимую форму. Драйвер можно инициализировать в переменной формы служебной внешней обработки. При первом обращении форма создается с фиксированным ключом уникальности и скрывается (устанавливается свойство Видимость = Ложь), после чего не закрывается до конца сеанса. При повторных вызовах метод ПолучитьФорму() с тем же ключом уникальности вернет ссылку на уже работающую в памяти форму с готовым инициализированным объектом драйвера.
  2. Использование расширений конфигурации. Если версия платформы поддерживает расширения, подключим собственное расширение к информационной базе без снятия основной конфигурации с поддержки. В нем можно создать свой клиентский общий модуль или глобальную переменную, где объект драйвера будет инициализироваться один раз при старте сеанса.
  3. Использование БПО (Библиотеки подключаемого оборудования). Если конфигурация типовая (или частично построена на базе БСП/БПО), в ней уже реализован механизм кэширования. Достаточно вызывать штатные клиентские функции подключения оборудования по его идентификатору. Платформа сама удержит дескриптор открытого порта и загруженный драйвер во внутреннем пуле до завершения работы пользователя.

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

← На главную