Параметры сеанса в 1С 8.3: где задать значение, как прочитать и отладить

· 9 мин

Содержание

Параметры сеанса в 1С инициализируют в модуле сеанса, в обработчике УстановкаПараметровСеанса(ТребуемыеПараметры). Платформа вызывает его при старте сеанса и потом каждый раз, когда код обращается к параметру, которому ещё не присвоено значение. Задача обработчика — записать значение в ПараметрыСеанса.ИмяПараметра для каждого имени из массива ТребуемыеПараметры.

Схема одна и та же и работает в любой конфигурации на платформе 8.3: от объявления параметра до отладки, когда он «не установлен». Тема общая для платформы, от конкретной конфигурации не зависит.

Что такое параметр сеанса и где его объявляют

Параметр сеанса — это значение, которое живёт ровно один сеанс пользователя. Его видит весь серверный код этого сеанса, но не видят другие сеансы. Типичные примеры:

  • 👤 текущий пользователь (ссылка на элемент справочника «Пользователи»);
  • 🏢 основная организация или подразделение пользователя;
  • 🔐 списки разрешённых значений для ограничений доступа на уровне записей (RLS);
  • 🧩 значение разделителя в базах с разделением данных;
  • 🛠 служебные флаги: режим отладки обменов, признак запуска из планировщика.

Объявляют параметр в Конфигураторе: в дереве метаданных Общие → Параметры сеанса, команда «Добавить». В свойствах задают имя, синоним и тип.

Допустимые типы — примитивные (Строка, Число, Дата, Булево), ссылки на объекты конфигурации, ХранилищеЗначения и фиксированные коллекции вроде ФиксированныйМассив. Обычный Массив или ТаблицаЗначений в параметр сеанса не положить: значение должно быть неизменяемым.

Если нужно хранить список — объявите тип ФиксированныйМассив, соберите обычный массив и перед записью оберните: Новый ФиксированныйМассив(Массив).

Чем параметр сеанса отличается от других способов хранить значение

СпособГде виденСколько живётКогда выбрать
Параметр сеансаВесь серверный код сеанса, тексты RLSДо конца сеансаПользователь, организация, данные для ограничений доступа
Глобальная переменная модуля приложенияТолько клиентДо закрытия клиентаКлиентские настройки интерфейса
Модуль с повторным использованиемКод сервера или клиентаПока жив кешСправочные значения, которые долго считать
КонстантаВсе сеансы и пользователиПостоянноОбщие настройки базы

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

Инициализация параметров сеанса в модуле сеанса

Модуль сеанса открывают из контекстного меню корня конфигурации: правой кнопкой по корню дерева → «Открыть модуль сеанса». Код там выполняется на сервере и в привилегированном режиме, поэтому права текущего пользователя на установку параметров не проверяются.

Обработчик получает один аргумент:

  • ТребуемыеПараметры = Неопределено — вызов при начале сеанса;
  • ТребуемыеПараметры — массив строк с именами параметров, к которым обратились, а значения у них ещё нет.

Вариант 1. Всё сразу при старте

Самый простой путь — при старте заполнить все параметры. Подходит, если их три-пять и каждый считается быстро.

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

    Если ТребуемыеПараметры = Неопределено Тогда
        УстановитьТекущегоПользователя();
        УстановитьОсновнуюОрганизацию();
    КонецЕсли;

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

Минус очевиден: каждый вход, каждое фоновое задание и каждый вызов HTTP-сервиса платит за расчёт всех значений, даже если они не понадобятся.

Вариант 2. Ленивая инициализация

Правильнее ничего не считать при старте и заполнять параметр только по требованию. Платформа сама передаст имя, когда код впервые прочитает ПараметрыСеанса.ОсновнаяОрганизация.

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

    Если ТребуемыеПараметры = Неопределено Тогда
        // Старт сеанса: значения посчитаем при первом обращении
        Возврат;
    КонецЕсли;

    Для Каждого ИмяПараметра Из ТребуемыеПараметры Цикл

        Если ИмяПараметра = "ТекущийПользователь" Тогда
            УстановитьТекущегоПользователя();

        ИначеЕсли ИмяПараметра = "ОсновнаяОрганизация" Тогда
            УстановитьОсновнуюОрганизацию();

        ИначеЕсли ИмяПараметра = "РежимОтладкиОбменов" Тогда
            ПараметрыСеанса.РежимОтладкиОбменов = Ложь;

        КонецЕсли;

    КонецЦикла;

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

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

Пример: текущий пользователь

Классическая задача — связать пользователя информационной базы с элементом справочника. Ниже предполагается, что в справочнике Пользователи есть реквизит ИдентификаторПользователяИБ типа УникальныйИдентификатор.

Процедура УстановитьТекущегоПользователя()

    ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();

    Ссылка = Справочники.Пользователи.НайтиПоРеквизиту(
        "ИдентификаторПользователяИБ", ПользовательИБ.УникальныйИдентификатор);

    // Не нашли — пишем пустую ссылку, но параметр установлен
    ПараметрыСеанса.ТекущийПользователь = Ссылка;

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

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

Когда вызывается обработчик

СеансВызов при стартеЛенивая установка
Тонкий и веб-клиентДаДа
Фоновое и регламентное заданиеДа, у задания свой сеансДа
HTTP- и веб-сервисДа, на каждый новый сеансДа
COM-соединениеДаДа

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

Права доступа и безопасный режим

Вне модуля сеанса установка подчиняется правам. В каждой роли у параметра сеанса два права: «Получение» и «Установка». Открываются они в редакторе роли, в ветке Общие → Параметры сеанса.

  • 📖 нет права «Получение» — чтение ПараметрыСеанса.Имя даст ошибку нарушения прав доступа;
  • ✏️ нет права «Установка» — так же упадёт запись.

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

Процедура УстановитьОрганизациюСеанса(Знач Организация) Экспорт

    УстановитьПривилегированныйРежим(Истина);
    ПараметрыСеанса.ОсновнаяОрганизация = Организация;
    УстановитьПривилегированныйРежим(Ложь);

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

Такой метод нельзя делать доступным с клиента без проверки входных данных. Если параметр участвует в RLS, пользователь, передавший чужую организацию, получит доступ к её документам.

Безопасный режим

Внешние обработки и отчёты, расширения в безопасном режиме и код, выполненный после УстановитьБезопасныйРежим(Истина), работают с ограничениями. Главное для нашей темы: в безопасном режиме нельзя включить привилегированный режим. Поэтому приём с УстановитьПривилегированныйРежим из внешней обработки не сработает — платформа выдаст ошибку.

Что делать:

  1. Перенести установку параметра в общий модуль самой конфигурации или в расширение без безопасного режима.
  2. Из внешней обработки вызывать этот метод, а не писать в ПараметрыСеанса напрямую.
  3. Проверять в методе, что переданное значение допустимо для текущего пользователя.

Безопасный режим разделения данных

В базах с разделением данных разделитель берёт значение из параметра сеанса. После вызова УстановитьБезопасныйРежимРазделенияДанных код не может поменять значения параметров сеанса, связанных с разделителями. Это защищает от «переключения» на чужую область данных. Если в такой базе обработчик пытается сменить область — проверьте, не включён ли этот режим выше по стеку.

Передача значения через ключ /C командной строки

Иногда параметр сеанса нужно задать снаружи: ярлык для оператора склада, запуск из планировщика, тестовый стенд. Для этого есть ключ /C — произвольная строка, которую клиент получает в свойстве ПараметрЗапуска.

"C:\Program Files\1cv8\common\1cestart.exe" ENTERPRISE /F"D:\Bases\Trade" /N"Склад" /C"DebugExchange"

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

  1. В модуле управляемого приложения, в обработчике ПриНачалеРаботыСистемы, прочитайте ПараметрЗапуска.
  2. Передайте строку в серверный общий модуль с флагом «Вызов сервера».
  3. Там разберите строку и установите параметр в привилегированном режиме.
// Модуль управляемого приложения
Процедура ПриНачалеРаботыСистемы()
    Если Не ПустаяСтрока(ПараметрЗапуска) Тогда
        ПараметрыСеансаВызовСервера.ПрименитьСтрокуЗапуска(ПараметрЗапуска);
    КонецЕсли;
КонецПроцедуры

// Общий модуль ПараметрыСеансаВызовСервера (Сервер, Вызов сервера)
Процедура ПрименитьСтрокуЗапуска(Знач СтрокаЗапуска) Экспорт
    УстановитьПривилегированныйРежим(Истина);
    ПараметрыСеанса.РежимОтладкиОбменов =
        СтрНайти(ВРег(СтрокаЗапуска), "DEBUGEXCHANGE") > 0;
КонецПроцедуры

В конфигурациях на БСП через /C уже передают служебные команды, например ЗапуститьОбновлениеИнформационнойБазы или ЗавершитьРаботуПользователей. Несколько ключей разделяют точкой с запятой, и ваш разбор строки должен это учитывать.

Ключ /C может набрать любой пользователь, у которого есть ярлык. Через него стоит передавать только флаги удобства и отладки. Права, организацию для RLS и всё, что влияет на доступ к данным, через командную строку не задают.

Программная установка и чтение значений параметров сеанса

Писать в параметр можно из любого серверного кода, если хватает прав. Чтение тоже только на сервере: на клиенте объекта ПараметрыСеанса нет.

Как получить значение на клиенте

Сделайте серверную функцию и вызывайте её с клиента. Если значение за сеанс не меняется, поместите функцию в общий модуль с повторным использованием «На время сеанса» — тогда сервер будет вызываться один раз.

// Общий модуль ПараметрыСеансаПовтИсп (Сервер, Вызов сервера,
// Повторное использование: На время сеанса)
Функция ТекущийПользователь() Экспорт
    Возврат ПараметрыСеанса.ТекущийПользователь;
КонецФункции

Если параметр может измениться в течение сеанса (пользователь сменил организацию), кеш вернёт старое значение. Для таких параметров повторное использование не включайте.

Параметры сеанса в запросах и RLS

В тексте ограничения доступа к параметру сеанса обращаются через амперсанд, как к параметру запроса: ГДЕ Организация = &ОсновнаяОрганизация. Платформа подставит значение сама и при необходимости вызовет ленивую инициализацию.

В обычном запросе такой автоподстановки нет. Значение передают явно:

Запрос.УстановитьПараметр("Организация", ПараметрыСеанса.ОсновнаяОрганизация);

Как поменять значение посреди сеанса

Просто присвойте новое значение в серверном коде с нужными правами. Помните про последствия:

  • 🔄 кеши модулей с повторным использованием не сбросятся сами — вызовите ОбновитьПовторноИспользуемыеЗначения() на клиенте;
  • 📋 уже открытые формы списков не перечитают данные — RLS применится к следующему запросу;
  • 🧵 запущенные ранее фоновые задания нового значения не увидят.

Диагностика и отладка параметров сеанса

Самая частая проблема — параметр «не установлен» или установлен не тем значением. Отладку начните с того, кто и когда вызывает обработчик.

Как поймать момент инициализации

  1. Включите отладку на сервере: служба агента сервера запускается с ключом -debug (для файловой базы не нужно).
  2. В Конфигураторе поставьте точку останова в первой строке УстановкаПараметровСеанса.
  3. Запустите отладку из Конфигуратора (F5), чтобы отладчик подключился до старта сеанса.
  4. Посмотрите значение ТребуемыеПараметры: Неопределено — старт сеанса, массив — ленивая установка конкретного параметра.
  5. В стеке вызовов (Ctrl+Alt+C) найдите строку, которая обратилась к параметру. Это и есть место, где значение понадобилось впервые.

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

Текущее значение в любой точке останова смотрят через «Вычислить выражение» (Shift+F9): введите ПараметрыСеанса.ТекущийПользователь. Если параметр ещё не установлен, само вычисление запустит инициализацию — учитывайте это при анализе.

Быстрая диагностика по симптому

Диагностика: выберите симптом

Если вход падает с ошибкой в модуле сеанса

Исключение в УстановкаПараметровСеанса при старте не даст войти никому, включая администратора в режиме Предприятия. Конфигуратор при этом открывается: модуль сеанса в нём не выполняется. Исправьте код там.

Чтобы не попадать в такую ситуацию, оборачивайте расчёт необязательных значений в Попытка ... Исключение, пишите ошибку в журнал регистрации через ЗаписьЖурналаРегистрации и ставьте безопасное значение по умолчанию. Обязательные для доступа параметры, наоборот, лучше оставить без «глушения»: пустая организация в RLS хуже явной ошибки.

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

Можно ли хранить в параметре сеанса таблицу значений?
Напрямую нет — тип должен быть неизменяемым. Положите таблицу в ХранилищеЗначения или разбейте на ФиксированныйМассив структур.
Сохраняется ли значение после переподключения клиента?
Нет. Новый сеанс начинается с пустыми параметрами, и обработчик УстановкаПараметровСеанса вызывается заново.
Влияют ли параметры сеанса на лицензии и число сеансов?
Нет. Это просто значения внутри уже открытого сеанса, отдельной лицензии они не занимают.
Видят ли параметры сеанса другие пользователи или администратор в консоли кластера?
Нет. Значения живут только внутри своего сеанса. Чтобы посмотреть их у пользователя, нужна отладка его сеанса или запись значений в журнал регистрации.
Можно ли установить параметр сеанса в расширении?
Да. В расширении объявляют собственные параметры сеанса и задают их значения в модуле сеанса расширения. Для установки параметров с правами нужно расширение без безопасного режима.