Как передать значения параметров сеанса в клиентский код 1С 8.3

· 10 мин

Содержание

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

Какой способ выбрать, решает частота обращений. Нужно одно значение в одной форме — хватит реквизита. Значение читают десятки форм и команд — нужен кэш, иначе каждое обращение превращается в отдельный серверный вызов. Всё это одинаково работает в тонком, веб- и мобильном клиенте.

Где хранятся данные сеанса и почему клиент их не видит

Параметр сеанса — объект метаданных из ветки Общие → Параметры сеанса. Его значение живёт на сервере 1С, пока жив сеанс. Закрыли программу — значения пропали. Открыли второе окно 1С тем же пользователем — это новый сеанс со своими значениями.

Клиентское приложение не держит копию этих данных. Поэтому строка в модуле формы

&НаКлиенте
Процедура Команда1(Команда)
	Организация = ПараметрыСеанса.ТекущаяОрганизация;
КонецПроцедуры

не пройдёт проверку модулей: для клиента такой переменной нет. Та же строка внутри процедуры с директивой &НаСервере или &НаСервереБезКонтекста работает.

Схема доступа выглядит так:

  • 🖥 Клиент — модули форм с &НаКлиенте, клиентские общие модули, модуль управляемого приложения. ПараметрыСеанса недоступны.
  • 🔁 Серверный вызов — общий модуль с флагами «Сервер» и «Вызов сервера» или процедура формы &НаСервере. Через него клиент забирает значения.
  • 🗄 Сервер — модуль сеанса, серверные общие модули, модули объектов и менеджеров. Здесь ПараметрыСеанса читаются и устанавливаются.

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

Четыре способа получить параметры сеанса на клиенте

СпособКогда подходитСерверных вызововМинусы
Реквизит формы из ПриСозданииНаСервереЗначение нужно одной форме0 дополнительныхТолько внутри этой формы
Функция общего модуля «Вызов сервера»Редкое разовое обращение1 на каждый вызовДорого в цикле и в частых обработчиках
Клиентский модуль «На время сеанса»Значение читают многие формы1 за сеансНе видит изменений без сброса кэша
Параметры работы клиента БСПКонфигурация на БСП (БП, ЗУП, УТ и др.)Входит в стартовый вызовПравка переопределяемого модуля

Реквизит формы

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

Серверная функция

Самый прямой путь. Пишется общий модуль с флажками «Сервер» и «Вызов сервера», в нём экспортная функция возвращает нужные значения. Клиент вызывает её как обычную функцию.

Кэш на время сеанса

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

Параметры работы клиента в БСП

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

Как устроен параметр сеанса: тип, права, установка

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

  • 🏷 Имя — по нему обращаются в коде: ПараметрыСеанса.ТекущаяОрганизация.
  • 🧩 Тип — ссылка, примитивный тип или неизменяемая коллекция: ФиксированныйМассив, ФиксированнаяСтруктура. Обычный Массив или Структуру присвоить не получится.
  • 🔐 Права в ролях — у каждого параметра сеанса два права: «Получение» и «Установка». Без «Получения» обращение из серверного кода, работающего не в привилегированном режиме, падает с нарушением прав доступа.

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

Эта ленивая схема позволяет не считать всё при запуске:

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

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

	Для Каждого ИмяПараметра Из ТребуемыеПараметры Цикл
		Если ИмяПараметра = "ТекущаяОрганизация" Тогда
			ПараметрыСеанса.ТекущаяОрганизация = ОрганизацияПоУмолчанию();
		ИначеЕсли ИмяПараметра = "РежимОтладкиОбменов" Тогда
			ПараметрыСеанса.РежимОтладкиОбменов = Ложь;
		КонецЕсли;
	КонецЦикла;

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

Функцию ОрганизацияПоУмолчанию() здесь нужно написать самостоятельно в этом же модуле или в серверном общем модуле. Главное правило: каждый параметр, к которому обращается код, должен получить значение в какой-то ветке обработчика. Иначе первое же чтение закончится ошибкой.

Примеры кода: получение параметров сеанса на клиенте

Ниже — рабочая связка из трёх частей. Параметры условные: ТекущаяОрганизация (ссылка на справочник «Организации») и РежимОтладкиОбменов (булево).

Шаг 1. Серверная функция

Общий модуль ДанныеСеансаВызовСервера, флажки «Сервер» и «Вызов сервера»:

Функция ДанныеСеансаДляКлиента() Экспорт

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

	Возврат Новый ФиксированнаяСтруктура(Результат);

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

Представление организации передаём сразу строкой. Ссылка на клиенте есть, но получить её реквизиты без нового серверного вызова клиент не сможет.

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

Шаг 2. Клиентский кэш

Общий модуль ДанныеСеансаКлиентПовтИсп: флажок «Клиент (управляемое приложение)», повторное использование «На время сеанса»:

Функция ДанныеСеанса() Экспорт
	Возврат ДанныеСеансаВызовСервера.ДанныеСеансаДляКлиента();
КонецФункции

Шаг 3. Чтение в форме

&НаКлиенте
Процедура Сформировать(Команда)

	Данные = ДанныеСеансаКлиентПовтИсп.ДанныеСеанса();

	Если Не ЗначениеЗаполнено(Данные.ТекущаяОрганизация) Тогда
		ПоказатьПредупреждение(, "Не выбрана текущая организация.");
		Возврат;
	КонецЕсли;

	Сообщить("Отчёт по организации: " + Данные.ПредставлениеОрганизации);

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

Первый вызов ДанныеСеанса() сходит на сервер, все остальные за сеанс возьмут значение из кэша.

Если значение меняется по ходу сеанса

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

Вариант через реквизит формы

Для одной формы кэш избыточен. Создайте реквизит ТекущаяОрганизация нужного типа и заполните его при создании:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	ТекущаяОрганизация = ПараметрыСеанса.ТекущаяОрганизация;
КонецПроцедуры

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

Установка параметра по запросу с клиента

Иногда клиент должен не только прочитать, но и поменять значение. Это тоже делается через сервер:

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

	Если Не ПравоДоступа("Чтение", Метаданные.Справочники.Организации) Тогда
		ВызватьИсключение "Недостаточно прав для выбора организации.";
	КонецЕсли;

	ПараметрыСеанса.ТекущаяОрганизация = Организация;

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

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

Что о сеансе можно узнать прямо на клиенте

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

Что нужноЧем получить на клиенте
Имя пользователя информационной базыИмяПользователя(), ПолноеИмяПользователя()
Строка запуска с ключом /CСвойство глобального контекста ПараметрЗапуска
Строка соединения с базойСтрокаСоединенияИнформационнойБазы()
Версия платформы, ОС клиента, ОЗУНовый СистемнаяИнформация
Скорость соединенияПолучитьСкоростьКлиентскогоСоединения()
Дата и время сеансаТекущаяДатаСеанса()

Пример для ПараметрЗапуска: ярлык запуска с ключом /C"Отладка" позволяет включить в клиентском коде дополнительную диагностику.

&НаКлиенте
Процедура ПриОткрытии(Отказ)

	Если СтрНайти(ПараметрЗапуска, "Отладка") > 0 Тогда
		Сис = Новый СистемнаяИнформация;
		Сообщить("Платформа " + Сис.ВерсияПриложения + ", ОС: " + Сис.ВерсияОС);
	КонецЕсли;

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

А вот номер сеанса, время его начала, имя компьютера и приложения берут на сервере. Функция ПолучитьТекущийСеансИнформационнойБазы() возвращает объект СеансИнформационнойБазы со свойствами НомерСеанса, НачалоСеанса, ИмяКомпьютера, ИмяПриложения. Передать их клиенту можно той же серверной функцией из примера выше.

Особенности веб-клиента

Код и подход в веб-клиенте те же. ПараметрыСеанса на клиенте недоступны, серверная функция и кэш работают без изменений. Разница — в цене и деталях.

  • 🌐 Каждый серверный вызов — отдельный HTTP-запрос через веб-сервер с публикацией базы. Задержка заметно выше, чем у тонкого клиента в локальной сети. Кэш «На время сеанса» здесь даёт самый ощутимый выигрыш.
  • 🚫 Не читайте данные сеанса в частых обработчиках вроде ПриАктивизацииСтроки или в цикле по строкам таблицы. В веб-клиенте это превращается в серию запросов и подвисание формы.
  • 🧭 Браузер вместо ОС. СистемнаяИнформация в веб-клиенте возвращает свойство ИнформацияПрограммыПросмотра — строку агента браузера. По ней определяют браузер пользователя.
  • 🔗 Параметр запуска в веб-клиенте передают в адресе публикации параметром C, затем он доступен в ПараметрЗапуска.
  • 🔄 Обновление страницы браузера — новый сеанс. Параметры сеанса снова пустые, клиентский кэш сброшен, обработчик УстановкаПараметровСеанса отработает заново.

Диагностика и отладка значений

Когда клиент показывает «не то», нужно понять, на каком шаге значение испортилось: в модуле сеанса, при передаче или в кэше.

  1. Поставьте точку останова в серверной функции ДанныеСеансаДляКлиента() и запустите отладку из Конфигуратора (F5).
  2. Когда выполнение остановится, нажмите Shift+F9 и вычислите ПараметрыСеанса.ТекущаяОрганизация. Это выражение считается только в серверном контексте: на точке останова в клиентской процедуре отладчик вернёт ошибку.
  3. Если значение уже на сервере неверное, ставьте точку в УстановкаПараметровСеанса и смотрите, какая ветка его заполнила.
  4. Если на сервере всё верно, а на клиенте старое значение — дело в кэше. Проверьте, вызывается ли ОбновитьПовторноИспользуемыеЗначения() после смены параметра.
  5. Если точка в серверной функции ни разу не сработала при повторном вызове — это нормальная работа кэша «На время сеанса», а не ошибка.

Для клиент-серверной базы отладка серверного кода требует, чтобы сервер 1С был запущен с разрешённой отладкой (ключ -debug у агента сервера). Включать его на рабочем сервере стоит согласовав с администратором: изменение параметров службы требует её перезапуска, а перезапуск оборвёт сеансы всех пользователей. Делайте это в нерабочее время или на тестовом сервере.

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

Ошибки при работе с параметрами сеанса

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

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

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

Нужен ли привилегированный режим, чтобы прочитать параметр сеанса?
Нет, если у роли пользователя есть право «Получение» на этот параметр. Привилегированный режим нужен только тогда, когда права намеренно не выдают, а значение всё же требуется серверному коду.
Можно ли обратиться к ПараметрыСеанса в процедуре &НаСервереБезКонтекста?
Да. Это серверный контекст, просто без данных формы. Такой вызов даже легче, чем &НаСервере: на сервер не передаются реквизиты формы.
Чем параметр сеанса отличается от экспортной переменной модуля приложения?
Переменная модуля приложения живёт на клиенте и доступна только клиентскому коду. Параметр сеанса живёт на сервере, участвует в ограничениях доступа и не может быть изменён клиентом в обход сервера.
Видит ли параметры сеанса внешняя обработка?
Да, в своих серверных процедурах, если у пользователя есть права на эти параметры. В клиентских процедурах обработки ограничение то же, что и для конфигурации.
Одинаковы ли параметры сеанса у двух окон 1С одного пользователя?
Нет. Каждое окно — отдельный сеанс со своими значениями и своим клиентским кэшем. Изменение в одном окне не появится в другом.