К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как объявить глобальную переменную на сервере в 1С

Как объявить глобальную переменную на сервере в 1С: модуль сеанса, Экспорт, разделители, параметры сеанса. Примеры кода, ошибки и проверка результата.

Во встроенном языке 1С нет привычных «глобальных переменных приложения» в стиле других языков: нельзя просто написать ГлобальнаяПеременная = Значение; в произвольном месте и читать её отовсюду. Область видимости переменной определяется модулем, в котором она объявлена, и директивами компиляции. Чтобы получить значение, доступное на сервере из разных процедур и модулей, используют несколько законных механизмов: экспортные переменные модуля сеанса, общие серверные модули с функциями-кешами, параметры сеанса и константы.

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

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

Почему в 1С нет классических глобальных переменных

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

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

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

Способ 1: экспортная переменная модуля сеанса

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

Чтобы создать такую переменную, откройте конфигуратор, найдите в дереве конфигурации «Общие → Модуль сеанса» и объявите переменную с ключевым словом Экспорт:

Перем ТекущийКурсВалюты Экспорт;

Перем ПризнакОбменаВыполняется Экспорт;

Обращение к переменной из любого серверного кода выполняется напрямую по имени, без префикса модуля:

// В общем серверном модуле или модуле объекта

ТекущийКурсВалюты = ПолучитьКурсИзРегистра(Валюта, ТекущаяДатаСеанса());

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

Инициализация при старте сеанса

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

Способ 2: общий серверный модуль с кеширующей функцией

Более управляемый вариант — общий модуль с установленными флагами «Сервер» и, при необходимости, «Вызов сервера». Вместо открытой переменной создают пару «закрытая переменная модуля + экспортная функция-геттер», которая вычисляет значение при первом обращении и дальше возвращает кешированное.

// Общий модуль ОбщегоНазначенияСервер (Сервер = Истина)

Перем КешНастроекОбмена;

Функция НастройкиОбмена() Экспорт

Если КешНастроекОбмена = Неопределено Тогда

КешНастроекОбмена = ЗагрузитьНастройкиИзБазы();

КонецЕсли;

Возврат КешНастроекОбмена;

КонецФункции

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

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

Способ 3: параметры сеанса

Если «глобальное» значение должно различаться по пользователям и устанавливаться при входе, правильный инструмент — параметры сеанса (ветка «Общие → Параметры сеанса» в конфигураторе). Это типизированные значения, доступные на чтение и запись из серверного кода через ПараметрыСеанса.ИмяПараметра.

// В модуле сеанса

Процедура УстановкаПараметровСеанса(ТребуемыеПараметры) Экспорт

ПараметрыСеанса.ТекущееПодразделение = НайтиПодразделениеПользователя();

КонецПроцедуры

// В любом серверном коде

Если ПараметрыСеанса.ТекущееПодразделение = Шапка.Подразделение Тогда

// ...

КонецЕсли;

Преимущество перед переменной модуля сеанса: параметры сеанса участвуют в механизме разделения данных и могут использоваться в ограничениях доступа к данным (RLS) на уровне запросов. Недостаток — тип параметра фиксируется в метаданных, и хранить там произвольные структуры нельзя, только значения указанных типов.

Способ 4: константы и хранение между сеансами

Если значение должно переживать перезапуск сеанса и сервера, никакая переменная не поможет — данные нужно писать в базу. Для одиночных значений (признак режима работы, текущий номер, настройка) предназначены константы: Константы.ИмяКонстанты.Установить(Значение) и Константы.ИмяКонстанты.Получить().

Для значений, различающихся по пользователям или измерениям, подойдёт регистр сведений. Чтение константы — это обращение к базе, поэтому в циклах и массовых обработках её значение принято читать один раз в локальную переменную, а не дёргать на каждой итерации.

Сравнение вариантов

Переменная модуля сеанса

Быстрый доступ без обращения к базе, живёт до конца сеанса. Не переживает перезапуск, не разделяется между сеансами.

Общий серверный модуль

Контролируемый кеш через функцию-геттер, можно сбросить. Требует аккуратности с флагами компиляции модуля.

Параметр сеанса

Индивидуален для пользователя, работает в RLS. Тип фиксирован в метаданных, структуры хранить нельзя.

Константа

Хранится в базе, переживает перезапуск, общая для всех. Каждое чтение — обращение к БД, не подходит для частого доступа в циклах.

Пошагово: создаём серверную глобальную переменную

Ниже — полный порядок действий для самого востребованного сценария: значение, вычисляемое один раз и доступное всему серверному коду в течение сеанса.

Порядок действий
  1. 1
    Откройте конфигуратор и перейдите: Общие → Модуль сеанса.
  2. 2
    Объявите переменную: Перем МоеЗначение Экспорт;
  3. 3
    В процедуре УстановкаПараметровСеанса или отдельной экспортной процедуре задайте начальное значение.
  4. 4
    Обновите конфигурацию базы данных (F7) — иначе изменения не попадут в серверный контекст.
  5. 5
    Из серверного кода обратитесь к переменной по имени и проверьте значение через отладчик или запись в журнал регистрации.

Проверка результата выполняется отладчиком: поставьте точку останова в серверной процедуре, которая читает переменную, и убедитесь, что значение заполнено. Если отладка сервера не настроена, временно выведите значение через ЗаписьЖурналаРегистрации и посмотрите его в журнале регистрации.

Контрольные точки

Как проверить результат

Компиляция модуля
Норма

Конфигурация обновляется без ошибок «Переменная не определена»

Тревожный признак

Ошибка компиляции — переменная объявлена не в том модуле или без Экспорт

Значение в отладчике
Норма

В серверной процедуре переменная содержит ожидаемое значение

Тревожный признак

Неопределено — инициализация не выполнилась или сеанс пересоздан

Повторный вызов
Норма

Значение сохраняется между вызовами в рамках сеанса

Тревожный признак

Значение теряется — где-то идёт переинициализация или обращение не к той переменной

Типичные ошибки и ограничения

Самая частая ошибка — объявление переменной в модуле приложения и попытка читать её на сервере. В управляемом приложении модуль приложения исполняется на клиенте, и серверный контекст его не видит. Вторая по частоте — пропущенное слово Экспорт: переменная компилируется, но снаружи модуля недоступна.

Ещё одна группа проблем связана с ожиданием, что переменная будет общей для всех пользователей. Серверные переменные изолированы по сеансам: если нужно «общее для всех» значение, используйте константу или регистр сведений, а не переменную. Обратная ошибка — хранение пользовательских данных в константе, из-за чего пользователи перезаписывают значения друг друга.

Типичные ошибки
01
Объявление переменной в модуле приложения — на сервере она недоступна, ошибка «Переменная не определена».
02
Пропущено слово Экспорт — переменная видна только внутри своего модуля.
03
Ожидание, что значение разделяется между сеансами — каждый сеанс имеет свой экземпляр.
04
Чтение константы в цикле вместо однократного чтения в переменную — лишние обращения к базе и падение производительности.
05
Забытое обновление конфигурации БД (F7) — сервер продолжает работать со старой версией модуля.

Отдельно стоит упомянуть фоновые задания и web-сервисы: они выполняются в собственных сеансах, поэтому переменные, установленные в интерактивном сеансе пользователя, там недоступны. Данные в фоновое задание передают через параметры метода ФоновыеЗадания.Выполнить, а не через «глобальные» переменные.

Маршрут решения

Как выбрать механизм

Значение нужно только в текущем сеансе и часто читаетсяЭкспортная переменная модуля сеанса или кеш-функция в общем серверном модуле
Значение индивидуально для пользователя и нужно в отборах доступаПараметр сеанса с установкой в УстановкаПараметровСеанса
Значение должно сохраняться между сеансами и перезапускамиКонстанта или регистр сведений
Нужно передать данные в фоновое заданиеПараметры метода ФоновыеЗадания.Выполнить, а не переменные

Частые вопросы

Можно ли объявить глобальную переменную, общую для всех пользователей?

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

Почему серверная процедура не видит переменную из модуля приложения?

В управляемом приложении модуль приложения компилируется и исполняется на клиенте. Серверный контекст формируют модуль сеанса и общие модули с флагом «Сервер». Перенесите переменную в модуль сеанса или в общий серверный модуль.

Чем параметр сеанса лучше переменной модуля сеанса?

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

Сохранится ли значение переменной после перезапуска сервера 1С?

Нет. Любые переменные модулей живут только в памяти рабочего процесса в рамках сеанса. Для хранения между перезапусками данные нужно записывать в базу — константы, регистры сведений, справочники.

Как передать значение в фоновое задание?

Через массив параметров метода ФоновыеЗадания.Выполнить — фоновое задание работает в отдельном сеансе и не видит переменных сеанса пользователя. Результат фонового задания возвращают через временное хранилище (помещение значения по адресу).

Где объявить переменную, доступную и на клиенте, и на сервере?

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

Итог

Что важно запомнить

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