Разработка и Конфигурация · 12 мин
Глобальная переменная в 1С: как объявить и правильно использовать
Как объявить глобальную переменную в 1С: модуль приложения, экспортные переменные, параметры сеанса. Примеры кода, типичные ошибки и ограничения.
Запрос «глобальная переменная 1С как» обычно означает практическую задачу: разработчику нужно хранить значение, доступное из разных процедур, форм или всего сеанса, и он ищет, как это объявить. В платформе 1С:Предприятие нет глобальных переменных в классическом смысле других языков, но есть несколько механизмов, которые решают эту задачу: переменные модуля с директивой «Экспорт», модуль обычного приложения или управляемого приложения, параметры сеанса и глобальный контекст.
Выбор механизма зависит от области видимости, которая нужна: внутри одного модуля, в пределах клиентского приложения или на уровне всего сеанса пользователя, включая серверный код. Неправильный выбор приводит к типичным проблемам — переменная «обнуляется» при вызове сервера, недоступна в другой форме или создаёт утечки памяти и ошибки при параллельной работе пользователей.
Ниже разобраны все рабочие способы объявления глобальных переменных в 1С, их ограничения, примеры кода и критерии выбора для типовых сценариев.
Как устроена видимость переменных в 1С
Встроенный язык 1С различает несколько уровней видимости. Локальные переменные объявляются внутри процедуры или функции и живут только во время её выполнения. Переменные модуля объявляются в начале модуля, до первой процедуры, и доступны всем процедурам этого модуля. Если к такой переменной добавить директиву «Экспорт», она станет доступна из других модулей — это и есть ближайший аналог глобальной переменной.
Важно понимать контекст исполнения. В управляемом приложении код делится на клиентский и серверный. Переменная, объявленная в клиентском модуле, физически не существует на сервере: при каждом серверном вызове контекст клиента туда не передаётся. Поэтому «глобальность» переменной всегда ограничена тем контекстом, где она объявлена.
Способ 1. Экспортная переменная общего модуля
Самый распространённый способ создать глобальную переменную — объявить её в общем модуле. Создайте общий модуль (например, «ГлобальныеПеременные»), снимите у него флажок «Сервер», если значение нужно только на клиенте, или оставьте серверный контекст для серверных данных. В разделе переменных модуля напишите:
Перем ТекущийПользовательИмя Экспорт;
Перем НастройкиОбмена Экспорт;
После этого обращение из любого места конфигурации выглядит так: ГлобальныеПеременные.НастройкиОбмена = Новый Структура;. Чтение — аналогично, через имя модуля и точку. Это работает и в толстом клиенте, и в тонком, если у модуля корректно выставлены флажки использования.
Ограничение способа: если общий модуль серверный, переменная живёт только в рамках одного серверного вызова. При следующем вызове сервера значение будет потеряно, потому что серверный контекст не сохраняет состояние между вызовами. Поэтому экспортные переменные серверных модулей подходят только как временное хранилище внутри одного вызова, а не как постоянные глобальные значения.
Способ 2. Переменные модуля управляемого приложения
Модуль управляемого приложения выполняется на клиенте и живёт всё время работы сеанса пользователя. Переменные, объявленные в нём с «Экспорт», доступны из любой клиентской формы и клиентского общего модуля. Это классическое место для глобальных клиентских переменных: текущих настроек интерфейса, кэша значений, состояния обмена данными.
// Модуль управляемого приложения
Перем КэшКурсовВалют Экспорт;
Процедура ПриНачалеРаботыСистемы()
КэшКурсовВалют = Новый Соответствие;
КонецПроцедуры
Обращение из формы: КэшКурсовВалют.Вставить("USD", Курс); — если переменная объявлена в модуле приложения, она доступна напрямую по имени в глобальном контексте клиента. Инициализировать такие переменные удобно в обработчике «ПриНачалеРаботыСистемы», чтобы к моменту первого обращения значение уже существовало.
Помните: при обрыве соединения и переподключении клиента модуль приложения инициализируется заново, и все переменные вернутся к начальным значениям. Не храните там данные, потеря которых критична для пользователя.
Способ 3. Параметры сеанса — глобальные значения уровня сеанса
Если значение нужно и на клиенте, и на сервере, и при этом оно относится к конкретному пользователю (текущая организация, дата запрета изменения данных, роль), правильный инструмент — параметры сеанса. Они создаются в ветке «Общие → Параметры сеанса» в конфигураторе, тип задаётся явно.
Инициализация выполняется в модуле сеанса, в обработчике «УстановкаПараметровСеанса»:
Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
ПараметрыСеанса.ТекущаяОрганизация = Справочники.Организации.НайтиПоНаименованию("Основная");
КонецПроцедуры
Обращение из любого кода: ПараметрыСеанса.ТекущаяОрганизация. Значение хранится на сервере, доступно в любом вызове и у каждого пользователя своё — это принципиальное отличие от переменных модуля. Именно поэтому параметры сеанса используются в механизме RLS (ограничение доступа на уровне записей).
Способ 4. Константы и регистры как постоянное хранилище
Любые переменные — временные: они исчезают при завершении сеанса. Если «глобальное» значение должно сохраняться между запусками программы (признак включённого обмена, глобальный префикс, настройка по умолчанию), используйте константу. Это объект конфигурации, значение которого хранится в базе данных и доступно отовсюду: Константы.РежимОтладки.Получить() и Константы.РежимОтладки.Установить(Истина).
Для набора значений с историей изменений подойдёт регистр сведений. Для клиентских пользовательских настроек, которые не должны попадать в общую базу, существует «ХранилищеОбщихНастроек» — оно сохраняет значения по ключу и привязывается к пользователю.
Сравнение вариантов
Подходит для временных значений в рамках одного контекста. Ограничение: серверный модуль теряет значение между вызовами.
Подходит для клиентских глобальных значений на время сеанса. Ограничение: недоступна на сервере, сбрасывается при перезапуске клиента.
Подходит для данных пользователя, нужных и на клиенте, и на сервере. Ограничение: инициализируется при старте сеанса, тип фиксирован в конфигураторе.
Подходит для постоянных настроек, общих для базы. Ограничение: одно значение на всю базу, изменение пишется в транзакции.
Пошагово: создать глобальную переменную в общем модуле
Типовая последовательность для клиентской глобальной переменной выглядит так. Сначала создаётся общий модуль, затем объявляется переменная, потом она инициализируется и используется.
- 1Откройте конфигуратор, ветка «Общие → Общие модули», создайте модуль «ГлобальныеЗначения»
- 2Установите флажки «Клиент (управляемое приложение)»; снимите «Сервер», если серверный доступ не нужен
- 3В тексте модуля до первой процедуры напишите: Перем ТекущееЗначение Экспорт;
- 4Инициализируйте переменную в модуле приложения в обработчике ПриНачалеРаботыСистемы
- 5Обращайтесь из форм и модулей через ГлобальныеЗначения.ТекущееЗначение
- 6Обновите конфигурацию базы данных (F7) и проверьте доступность переменной в отладчике
Проверка результата проста: поставьте точку останова в любой форме, обратитесь к переменной через имя модуля и убедитесь, что значение читается и не равно «Неопределено» (если только вы сами не записали «Неопределено»). Если при обращении возникает ошибка «Переменная не определена», чаще всего не стоит директива «Экспорт» или модуль недоступен в данном контексте (например, клиентский модуль вызывается с сервера).
Типичные ошибки и их последствия
Большинство проблем с глобальными переменными в 1С вызвано не синтаксисом, а непониманием контекстов исполнения. Ниже — ошибки, которые встречаются чаще всего.
Отдельно стоит упомянуть многопоточность фоновых заданий: фоновое задание выполняется в отдельном сеансе и не видит переменные вашего клиентского сеанса вообще. Передавать данные в фоновое задание нужно через параметры метода «Выполнить», а результат забирать через временное хранилище.
Перед тем как заводить новую глобальную переменную, проверьте типовые механизмы: часто нужное уже есть в параметрах сеанса (текущий пользователь), в функциональных опциях или в константах. Лишняя глобальная переменная усложняет отладку, потому что место, где её изменили, приходится искать по всей конфигурации.
Как проверить, что переменная работает правильно
После внедрения глобальной переменной стоит пройти короткую проверку в отладчике, чтобы исключить скрытые проблемы с контекстом и инициализацией.
Как проверить результат
Значение соответствует последнему присвоенному
Неопределено или ошибка «Переменная не определена»
Для клиентской переменной значение сохранилось
Значение сбросилось — переменная объявлена в серверном контексте
У каждого пользователя своё значение (параметр сеанса) или общее (константа) — как задумано
Пользователи «видят» чужие данные или наоборот теряют свои
Переменная инициализируется в ПриНачалеРаботыСистемы
Обращения падают до первого присваивания
Если проверка показывает, что значение теряется, почти всегда решение — перенести данные на уровень ниже: из переменной модуля в параметр сеанса, из параметра сеанса в константу или регистр. Обратный перенос (из базы в переменную) оправдан только для кэширования часто читаемых значений.
Частые вопросы
Можно ли объявить глобальную переменную прямо в модуле формы?
Можно объявить переменную модуля формы с директивой «Экспорт», и она будет доступна из других модулей через объект формы. Но на практике это неудобно: форма может быть закрыта, и обращение вызовет ошибку. Для межформенного обмена надёжнее использовать общий модуль или параметры формы.
Чем параметр сеанса лучше экспортной переменной?
Параметр сеанса живёт на сервере, доступен из любого вызова, индивидуален для каждого пользователя и участвует в механизме ограничения прав на уровне записей. Экспортная переменная существует только в своём контексте и теряется при смене контекста. Для данных пользователя параметр сеанса — правильный выбор.
Почему переменная «обнуляется» после вызова сервера?
Потому что она объявлена в серверном общем модуле. Сервер не сохраняет состояние модуля между вызовами: каждый вызов начинается с чистого контекста. Перенесите переменную в клиентский модуль приложения, либо используйте параметры сеанса или базу данных.
Видна ли глобальная переменная в фоновом задании?
Нет. Фоновое задание выполняется в отдельном сеансе со своим контекстом и не имеет доступа к переменным клиентского сеанса. Данные передаются через параметры при запуске задания, а результат возвращается через временное хранилище или сообщения пользователю.
Как сохранить глобальное значение между запусками программы?
Переменные для этого не подходят — они живут только внутри сеанса. Используйте константу для единственного значения, регистр сведений для набора значений или ХранилищеОбщихНастроек для персональных пользовательских настроек.
Влияют ли глобальные переменные на производительность?
Само объявление — практически нет. Влияет содержимое: большие таблицы значений и массивы в глобальных переменных увеличивают потребление памяти сеанса на всё время работы. Кэшируйте только действительно часто используемые данные и предусматривайте очистку.
Что важно запомнить
Глобальная переменная в 1С — это экспортная переменная общего модуля или модуля приложения. Она живёт только в своём контексте и внутри сеанса. Для данных, нужных на клиенте и сервере, используйте параметры сеанса, для постоянных значений — константы и регистры. Главная ошибка — хранить состояние в серверном модуле: оно теряется между вызовами без предупреждения.