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

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

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

Передача данных через параметры (Метод «Сквозного контекста»)

Самый правильный с точки зрения архитектуры способ — это явная передача данных. Если функция №1 подготавливает данные, а функция №2 должна их использовать, мы можем организовать передачу через параметры вызова. Чтобы не загромождать подписи функций десятками аргументов, разберем использование объекта Структура.

Проанализируем ситуацию: мы создаем одну структуру «Контекст», которую таскаем за собой через все вызовы. Это делает код прозрачным и упрощает отладку, так как мы всегда видим, какие данные поступили «на вход».


// В вызывающем коде
КонтекстДанных = Новый Структура;
ОбщийМодуль.Функция1(КонтекстДанных);
// ... какой-то промежуточный код ...
ОбщийМодуль.Функция2(КонтекстДанных);

// В общем модуле
Процедура Функция1(Контекст) Экспорт
    Контекст.Вставить("ВажныйРезультат", 42);
КонецПроцедуры

Процедура Функция2(Контекст) Экспорт
    Если Контекст.Свойство("ВажныйРезультат") Тогда
        Сообщить(Контекст.ВажныйРезультат);
    КонецЕсли;
КонецПроцедуры

Использование параметров сеанса

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

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

Временное хранилище (ВременноеХранилище)

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

Посмотрим на пример реализации:


// Функция №1 помещает данные
АдресХранилища = ПоместитьВоВременноеХранилище(ТЗ_Результат, Новый УникальныйИдентификатор);

// Функция №2 извлекает данные по адресу
НужныеДанные = ПолучитьИзВременногоХранилища(АдресХранилища);

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

Общие модули с повторным использованием возвращаемых значений

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

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

Модуль управляемого приложения (для клиента)

Если ваша задача ограничивается только клиентским контекстом (например, нужно передать данные между двумя общими модулями, работающими «НаКлиенте»), вы можете объявить экспортную переменную в Модуле управляемого приложения.

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


// В модуле управляемого приложения
Перем ГлобальныйКонтекстКлиента Экспорт;

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

Хранилище общих настроек

Для случаев, когда переменную нужно сохранить не просто до конца вызова, а между разными сеансами работы пользователя (например, «запомнить» выбор пользователя в функции №1, чтобы предложить его в функции №2 завтра), используйте ХранилищеОбщихНастроек.

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

Использование менеджера временных таблиц

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

Подведем итог: выбор замены глобальной переменной зависит от контекста. Для быстрой передачи «здесь и сейчас» используйте Структуру в параметрах. Для данных сеанса на сервере — Параметры сеанса. Для тяжелых объектов — Временное хранилище. А для кэширования сложных вычислений — механизмы повторного использования значений общего модуля.

← На главную