Параметры сеанса в 1С 8.3: от объявления в дереве до чтения из кода

· 9 мин

Содержание

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

Дальше начинаются нюансы, на которых спотыкаются даже опытные разработчики. Параметр не виден на клиенте, не переносится в фоновое задание, а в запрос сам не попадает. Разберём весь путь: объявление, инициализацию, использование в коде, запросах, СКД и внешнем соединении, а также отладку.

Механизм общий для платформы и не зависит от конфигурации. Он одинаково работает в Бухгалтерии, ЗУП, УТ и в самописных решениях.

Что такое параметр сеанса и когда он нужен

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

Хранится оно на сервере, поэтому к нему есть доступ из любого серверного кода без лишних вызовов.

Типичные задачи:

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

Чем параметр сеанса отличается от соседних механизмов:

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

Если значение нужно в тексте ограничения доступа, альтернативы нет: RLS умеет обращаться только к параметрам сеанса.

Как добавить параметр сеанса в конфигураторе

Порядок действий в конфигураторе 8.3:

  1. Откройте конфигурацию: Конфигурация → Открыть конфигурацию.
  2. В дереве метаданных раскройте ветку Общие.
  3. Найдите узел Параметры сеанса, щёлкните по нему правой кнопкой и выберите Добавить.
  4. На вкладке основных свойств задайте Имя латиницей или кириллицей без пробелов, например ТекущийСотрудник.
  5. Заполните Синоним — так параметр будет называться в интерфейсе ролей.
  6. Укажите Тип: ссылку на справочник, строку, число, булево, дату или фиксированную коллекцию.
  7. Сохраните изменения и обновите конфигурацию базы данных (F7).

Какие типы допустимы

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

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

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

Если в RLS нужен список значений, объявите тип ФиксированныйМассив. Обычный массив платформа в параметр сеанса записать не даст.

Права в ролях

У каждого параметра сеанса в роли два права: Получение и Установка. Откройте нужную роль, найдите в её дереве объектов ветку Параметры сеанса и отметьте права.

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

Заполнение значения в модуле сеанса

Модуль сеанса открывается из контекстного меню корня конфигурации: щёлкните правой кнопкой по самому верхнему узлу дерева и выберите Открыть модуль сеанса.

Модуль выполняется на сервере в привилегированном режиме. Права ролей на установку здесь не проверяются.

Как платформа вызывает обработчик

Процедура УстановкаПараметровСеанса срабатывает в двух ситуациях:

  1. При старте сеанса. Параметр ТребуемыеПараметры равен Неопределено.
  2. При первом обращении к незаполненному параметру. В ТребуемыеПараметры приходит массив строк с именами параметров, которые нужны прямо сейчас.

Отсюда два подхода. Заполнить всё сразу — просто, но удлиняет вход в программу. Заполнять лениво, по требованию, — чуть больше кода, зато сеанс стартует быстро.

Пример ленивой инициализации

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

    Если ТребуемыеПараметры = Неопределено Тогда
        // Старт сеанса: заполняем только самое лёгкое
        ПараметрыСеанса.РежимОбмена = Ложь;
        Возврат;
    КонецЕсли;

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

        Если ИмяПараметра = "ТекущийСотрудник" Тогда
            ПараметрыСеанса.ТекущийСотрудник = НайтиСотрудника();

        ИначеЕсли ИмяПараметра = "ДоступныеСклады" Тогда
            ПараметрыСеанса.ДоступныеСклады = Новый ФиксированныйМассив(ПолучитьСклады());

        КонецЕсли;

    КонецЦикла;

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

Функция НайтиСотрудника()

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |    Сотрудники.Ссылка КАК Ссылка
    |ИЗ
    |    Справочник.Сотрудники КАК Сотрудники
    |ГДЕ
    |    Сотрудники.Пользователь = &Пользователь";
    Запрос.УстановитьПараметр("Пользователь", ПользователиИнформационнойБазы.ТекущийПользователь().Имя);

    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        Возврат Выборка.Ссылка;
    КонецЕсли;

    Возврат Справочники.Сотрудники.ПустаяСсылка();

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

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

Всегда записывайте в параметр какое-то значение, даже пустую ссылку. Если обработчик ничего не присвоил, следующее обращение снова вызовет его, а затем завершится ошибкой.

Смена и сброс значения по ходу работы

Значение можно перезаписать в любом серверном коде:

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

Привилегированный режим нужен, если у роли пользователя нет права «Установка». Включайте его только на время присваивания.

Чтобы заставить платформу пересчитать значение, параметр сбрасывают методом ПараметрыСеанса.Сбросить(), передав массив имён. При следующем обращении снова сработает УстановкаПараметровСеанса.

Чтение параметра в коде и на клиенте

На сервере всё просто: ПараметрыСеанса.ТекущийСотрудник. В клиентском коде объекта ПараметрыСеанса нет — попытка обратиться к нему в процедуре с директивой &НаКлиенте даст ошибку при проверке модуля.

Рабочий способ — серверная функция в общем модуле с флагами «Сервер» и «Вызов сервера»:

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

    УстановитьПривилегированныйРежим(Истина);
    Возврат ПараметрыСеанса.ТекущийСотрудник;

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

На клиенте вызывайте РаботаСПараметрамиСеансаВызовСервера.ТекущийСотрудник().

Если значение нужно на клиенте часто, не дергайте сервер каждый раз. Заведите клиентский общий модуль с повторным использованием «На время сеанса» и оберните вызов в него — сервер будет опрошен один раз.

Не возвращайте на клиент ХранилищеЗначения целиком без нужды. Извлеките из него только те данные, которые понадобятся форме.

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

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

Обычный запрос

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    Заказ.Ссылка КАК Ссылка
|ИЗ
|    Документ.ЗаказКлиента КАК Заказ
|ГДЕ
|    Заказ.Ответственный = &Ответственный";
Запрос.УстановитьПараметр("Ответственный", ПараметрыСеанса.ТекущийСотрудник);

Код выполняется на сервере, поэтому дополнительных вызовов не требуется.

Система компоновки данных

В схеме компоновки объявите параметр, например Ответственный, и снимите у него признак доступности пользователю, если подставляете значение программно. Значение задайте в модуле отчёта на сервере:

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)

    Параметр = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(
        Новый ПараметрКомпоновкиДанных("Ответственный"));
    Если Параметр <> Неопределено Тогда
        Параметр.Значение = ПараметрыСеанса.ТекущийСотрудник;
        Параметр.Использование = Истина;
    КонецЕсли;

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

Стандартную обработку здесь не отключаем: отчёт сформируется штатно, просто с уже заполненным параметром.

Ограничение доступа на уровне записей

В тексте ограничения RLS параметры сеанса доступны напрямую, по имени через амперсанд:

ГДЕ ЗаказКлиента.Ответственный = &ТекущийСотрудник

Для списка значений с типом ФиксированныйМассив используйте В (&ДоступныеСклады). Платформа подставит текущее значение сама и при необходимости вызовет инициализацию.

Фоновые задания, внешнее соединение и COM

Каждое фоновое задание, внешнее соединение и COM-подключение — это отдельный сеанс. Для него модуль сеанса выполняется заново, а значения из сеанса, который запустил задание, не наследуются.

Фоновое задание

Если задание должно работать с тем же сотрудником, передайте значение параметром:

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

ФоновыеЗадания.Выполнить("ОбработкаЗаказов.Обработать", ПараметрыЗадания);

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

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

Внешнее соединение и COM

При подключении через V83.COMConnector в базе стартует сеанс типа «внешнее соединение». Платформа вызовет УстановкаПараметровСеанса так же, как для обычного входа.

Чтобы прочитать значение снаружи, удобнее всего экспортная функция общего модуля с флагом «Внешнее соединение»:

// Вызывающая сторона, например другая база 1С
Коннектор = Новый COMОбъект("V83.COMConnector");
Соединение = Коннектор.Connect("Srvr=""server1"";Ref=""trade"";Usr=""Обмен"";Pwd=""***"";");

Сотрудник = Соединение.РаботаСПараметрамиСеансаВызовСервера.ТекущийСотрудник();

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

Обработчик модуля сеанса не должен открывать формы и обращаться к клиентским объектам. Во внешнем соединении и в фоновом задании интерфейса нет, такой код упадёт и не даст создать сеанс.

Отладка и типичные проблемы

Модуль сеанса отлаживается как обычный серверный модуль. Поставьте точку останова в УстановкаПараметровСеанса и запустите отладку из конфигуратора. Для клиент-серверной базы на сервере 1С должна быть включена серверная отладка, иначе точки на сервере не сработают.

Текущее значение удобно посмотреть через окно вычисления выражения (Shift+F9) в момент остановки на сервере: введите ПараметрыСеанса.ТекущийСотрудник.

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

Зацикливание инициализации

Обработчик может читать другой параметр сеанса, который ещё не заполнен. Тогда платформа рекурсивно вызовет УстановкаПараметровСеанса для него. Это нормально, пока нет круга: параметр А ждёт Б, а Б ждёт А. Такой круг приводит к ошибке инициализации, и сеанс не стартует.

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

Проверка после изменений

После добавления параметра пройдитесь по короткому списку:

Параметр сеанса готов к работе
Выполнено: 0 / 6

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

Можно ли хранить в параметре сеанса таблицу значений?
Напрямую нет. Поместите таблицу в Новый ХранилищеЗначения(Таблица) и объявите тип ХранилищеЗначения. Для чтения используйте метод Получить().
Сохраняется ли значение после перезапуска программы?
Нет. Значение живёт только в текущем сеансе. Для настроек, которые должны пережить перезапуск, подходят константы или хранилище общих настроек.
Видят ли другие пользователи значение моего параметра сеанса?
Нет. У каждого сеанса своё значение, даже если один пользователь открыл программу дважды.
Чем параметр сеанса лучше экспортной переменной модуля управляемого приложения?
Переменная модуля приложения живёт на клиенте и недоступна серверному коду, запросам и RLS. Параметр сеанса хранится на сервере, поэтому его видят серверные модули, запросы и тексты ограничений RLS.
Можно ли поменять тип уже работающего параметра?
Можно, но проверьте все места, где ему присваивают значение: старый код начнёт падать с ошибкой типа. Поиск по ПараметрыСеанса.Имя во всей конфигурации (Ctrl+Shift+F) покажет каждое такое место.
Почему изменение значения в одной форме не видно в уже открытом клиентском кэше?
Клиентский модуль с повторным использованием запомнил старое значение. После смены параметра вызовите ОбновитьПовторноИспользуемыеЗначения() на клиенте.