Как в 1С создать глобальную переменную, доступную во всей программе?

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

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

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

Способ 1: Экспортные переменные модуля приложения (только для клиента)

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

Посмотрим на пример. Допустим, нам нужно хранить какое-то простое значение, доступное на клиенте в течение всего сеанса.

Шаг 1: Объявление переменной в модуле приложения

Откроем модуль управляемого приложения и в разделе переменных напишем:


// В модуле приложения
Перем МоеИмя Экспорт;

Шаг 2: Инициализация переменной

Присвоим ей значение, например, в обработчике события ПриНачалеРаботыСистемы, который выполняется на клиенте.


// В модуле приложения
Процедура ПриНачалеРаботыСистемы()
    МоеИмя = "Тест";
КонецПроцедуры

Шаг 3: Доступ к переменной

Теперь из модуля любой формы или из другого клиентского общего модуля мы можем напрямую обратиться к этой переменной.


// В модуле формы, в обработчике нажатия кнопки
&НаКлиенте
Процедура ПоказатьИмя(Команда)
    Сообщить(МоеИмя); // Выведет "Тест"
КонецПроцедуры

Важный момент: Этот способ работает только на клиенте. Если вы попытаетесь обратиться к переменной МоеИмя из серверного кода (например, из процедуры с директивой &НаСервере), вы получите ошибку «Переменная не определена». Именно это и произошло в исходной теме форума, когда автор пытался создать WSПрокси — объект, который часто используется на сервере, — и сохранить его в экспортной переменной модуля приложения.

Способ 2: Параметры сеанса (для клиента и сервера)

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

Главная проблема, с которой столкнулся автор темы, — в параметрах сеанса можно указывать только сериализуемые типы (число, строка, ссылка и т.д.). А как быть, если нужно сохранить сложный объект, например, ТипXDTO или WSПрокси? Решение — использовать универсальный тип ХранилищеЗначения.

Разберем по шагам, как поместить в параметр сеанса объект сложного типа.

  1. Создание параметра сеанса в конфигураторе. Перейдем в дерево конфигурации, найдем ветку «Общие» -> «Параметры сеанса». Создадим новый параметр, например, ТипGUIDXDTO и укажем для него тип ХранилищеЗначения.

  2. Инициализация параметра сеанса. Инициализация происходит на сервере в модуле сеанса, в специальной процедуре УстановкаПараметровСеанса. Этот код выполняется один раз при старте сеанса для каждого пользователя.

    
    // В Модуле сеанса
    Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
        
        // Создаем нужный нам сложный объект, например, ТипXDTO
        Фабрика = ФабрикиXDTO.v8;
        ТипGUID = Фабрика.Тип("http://www.w3.org/2001/XMLSchema", "string");
        
        // Помещаем его в ХранилищеЗначения и записываем в параметр сеанса
        ПараметрыСеанса.ТипGUIDXDTO = Новый ХранилищеЗначения(ТипGUID);
        
    КонецПроцедуры
    
  3. Получение значения из параметра сеанса. Теперь мы можем получить наш объект в любом месте кода. Важно помнить, что из хранилища его нужно извлечь с помощью метода Получить().

    На сервере:

    
    &НаСервере
    Процедура МояСервернаяПроцедура()
        // Получаем значение из параметра сеанса
        ХранилищеТипа = ПараметрыСеанса.ТипGUIDXDTO;
        
        // Извлекаем сам объект из хранилища
        Если ХранилищеТипа <> Неопределено Тогда
            МойТипGUID = ХранилищеТипа.Получить();
            // Теперь можно работать с переменной МойТипGUID
        КонецЕсли;
    КонецПроцедуры
    

    На клиенте:

    Напрямую получить доступ к ПараметрыСеанса с клиента нельзя. Сначала нужно получить значение на сервере и передать на клиент. Однако платформа предоставляет удобный доступ к параметрам сеанса через глобальную переменную контекста ПараметрыСеанса, которая кэшируется на клиенте. Значения, которые не могут быть переданы на клиент (как наш ТипXDTO), будут недоступны.

    Если же в параметре сеанса хранится примитивный тип (например, ссылка на текущего пользователя), его можно получить так:

    
    &НаКлиенте
    Процедура МояКлиентскаяПроцедура()
        // Этот код сработает, если в ПараметрыСеанса.ТекущийПользователь хранится ссылка
        ТекущийПользователь = ПараметрыСеанса.ТекущийПользователь; 
        Сообщить(ТекущийПользователь);
    КонецПроцедуры
    

Таким образом, Параметры сеанса в связке с ХранилищеЗначения — это мощный инструмент для создания «глобальных» сеансовых переменных, доступных на сервере.

Способ 3: Функции в общих модулях с кэшированием (для серверных объектов)

Этот метод является наиболее производительным и правильным для создания «глобальных» серверных объектов, инициализация которых — ресурсоемкая операция. Примерами могут быть COM-объекты, подключения к веб-сервисам (WS-прокси) или результаты выполнения сложных запросов, которые не меняются в течение сеанса.

Механизм основан на свойстве общего модуля «Повторное использование возвращаемых значений».

Шаг 1: Создание общего модуля

Создадим общий модуль, например, УправлениеСоединениями_ПовторноеИспользование. В его свойствах установим следующие флаги:

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

Шаг 2: Создание кэшируемой функции

В нашем модуле создадим экспортную функцию, которая будет создавать и возвращать объект WS-прокси.


// В общем модуле "УправлениеСоединениями_ПовторноеИспользование"
Функция ПолучитьПроксиСервер() Экспорт
    
    // При первом вызове этой функции в течение сеанса
    // платформа выполнит этот код и создаст объект
    Прокси = WSСсылки.Парсек.СоздатьWSПрокси(
        "http://...", 
        "IntegrationService", 
        "IntegrationServiceSoap");
    
    // Результат (созданный объект Прокси) будет помещен в кэш
    Возврат Прокси;
    
КонецФункции

Шаг 3: Использование функции

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


&НаСервере
Процедура ВыполнитьЗапросКВебСервису()
    // Получаем объект прокси. Если это первый вызов - он создастся.
    // Если второй, третий и т.д. - вернется из кэша.
    ПроксиСервер = УправлениеСоединениями_ПовторноеИспользование.ПолучитьПроксиСервер();
    
    // Работаем с объектом
    ПроксиСервер.ВыполнитьОперацию(...);
КонецПроцедуры

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

Итоги и рекомендации

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

  1. Для данных, нужных только на клиенте (например, для управления элементами интерфейса), используйте экспортные переменные модуля приложения. Это просто и быстро.

  2. Для данных, которые нужны и на клиенте, и на сервере в течение сеанса (настройки пользователя, его права, временные данные), используйте параметры сеанса. Для хранения сложных, несериализуемых объектов применяйте тип ХранилищеЗначения.

  3. Для «тяжелых» серверных объектов, которые нужно создавать один раз за сеанс (COM, WS-прокси, результаты сложных запросов), используйте функции в общих модулях со свойством «Повторное использование возвращаемых значений». Это самый производительный и правильный способ для таких задач.

  4. Для хранения данных, общих для всех пользователей и редко изменяемых, можно использовать константы. В них также можно помещать сложные типы через ХранилищеЗначения.

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

← На главную