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