При разработке конфигураций часто возникает задача инициализации параметров сеанса значениями, которые зависят от интерактивного выбора пользователя — например, выбор текущего рабочего места, кассы ККМ, склада или подразделения. Начинающие разработчики нередко пытаются вызвать интерактивные методы (ОткрытьФорму, Новый ОписаниеОповещения) непосредственно в процедуре УстановкаПараметровСеанса модуля сеанса, что приводит к синтаксическим ошибкам или аварийному завершению работы. Разберем, почему возникает эта ошибка и как архитектурно правильно реализовать интерактивную установку параметров сеанса.
Проанализируем контекст выполнения и архитектурные ограничения платформы 1С:Предприятие:
ОткрытьФорму) и типы для асинхронных вызовов (ОписаниеОповещения). Вызов клиентского кода напрямую с сервера невозможен.УстановкаПараметровСеанса выполняется не только при запуске тонкого или веб-клиента пользователем, но и при старте фоновых заданий, регламентных процессов, Web- и HTTP-сервисов, а также внешних соединений (COM). В таких сеансах пользовательского интерфейса нет в принципе, и любая попытка взаимодействия с клиентом приведет к падению фонового процесса.УстановкаПараметровСеанса срабатывает по требованию — при первом обращении к неинициализированному параметру из серверного кода. Если такое обращение произойдет в середине транзакции записи документа, прервать серверный поток для показа диалогового окна клиенту технически невозможно.Для решения задачи разделим процесс на три логических шага:
Неопределено / пустой ссылкой), чтобы серверный код не вызывал исключений.ПриНачалеРаботыСистемы модуля управляемого приложения.ПараметрыСеанса.Рассмотрим реализацию каждого этапа по шагам.
В модуле сеанса инициализируем параметр значением по умолчанию, если он еще не был установлен:
Процедура УстановкаПараметровСеанса(ИменаПараметровСеанса)
// Если список имен не задан, инициализируем нужные параметры
Если ИменаПараметровСеанса = Неопределено ИЛИ ИменаПараметровСеанса.Найти("ТекущееРабочееМесто") <> Неопределено Тогда
Если Не ЗначениеЗаполнено(ПараметрыСеанса.ТекущееРабочееМесто) Тогда
ПараметрыСеанса.ТекущееРабочееМесто = Справочники.РабочиеМеста.ПустаяСсылка();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Создадим общий модуль ПараметрыСеансаСервер со свойствами Сервер и Вызов сервера, в котором опишем процедуру фиксации выбранного значения:
// Общий модуль: ПараметрыСеансаСервер (Сервер, Вызов сервера)
Процедура УстановитьТекущееРабочееМесто(ВыбранноеРабочееМесто) Экспорт
ПараметрыСеанса.ТекущееРабочееМесто = ВыбранноеРабочееМесто;
КонецПроцедуры
Перенесем открытие формы выбора в обработчик события старта сеанса. В Модуле управляемого приложения вызываем форму с передачей объекта ОписаниеОповещения для обработки результата:
Процедура ПриНачалеРаботыСистемы()
// Формируем оповещение о завершении выбора
Оповещение = Новый ОписаниеОповещения("ПослеВыбораРабочегоМеста", ЭтотОбъект);
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("РежимВыбора", Истина);
// Открываем форму выбора блокирующим весь интерфейс окном
ОткрытьФорму(
"Справочник.РабочиеМеста.Форма.ФормаВыбора",
ПараметрыФормы,
ЭтотОбъект,
,
,
,
Оповещение,
РежимОткрытияОкнаФормы.БлокироватьВесьИнтерфейс
);
КонецПроцедуры
Процедура ПослеВыбораРабочегоМеста(РезультатВыбора, ДополнительныеПараметры) Экспорт
Если ЗначениеЗаполнено(РезультатВыбора) Тогда
// Записываем полученное значение в параметры сеанса на сервере
ПараметрыСеансаСервер.УстановитьТекущееРабочееМесто(РезультатВыбора);
Иначе
// Если выбор обязателен, а пользователь закрыл форму без выбора
ПоказатьПредупреждение(
Новый ОписаниеОповещения("ЗавершитьРаботуПриОтказе", ЭтотОбъект),
НСтр("ru = 'Для продолжения работы необходимо выбрать рабочее место!'")
);
КонецЕсли;
КонецПроцедуры
Процедура ЗавершитьРаботуПриОтказе(ДополнительныеПараметры) Экспорт
ЗавершитьРаботуСистемы(Ложь);
КонецПроцедуры
Посмотрим на более удобный сценарий, который применяется в типовых конфигурациях и Библиотеке стандартных подсистем (БСП). Чтобы не заставлять пользователя каждый раз вручную выбирать значение из справочника, рабочее место идентифицируется автоматически:
СистемнаяИнформация.ИдентификаторКлиента или имя компьютера).