При разработке в среде 1С:Предприятие 8 начинающие разработчики часто сталкиваются с ситуацией, когда необходимо уведомить пользователя о событии, произошедшем на сервере (например, появление нового заказа или изменение статуса документа). Попытка вызвать клиентскую процедуру из серверного модуля напрямую приводит к ошибке "Переменная не определена" или "Процедура или функция с указанным именем не определена". Разберем подробно, почему так происходит, и как правильно реализовать интерактивные оповещения.
Проанализируем архитектуру системы. В 1С существует строгое разделение контекстов выполнения. Серверный код выполняется на стороне сервера приложений, где нет графического интерфейса, окон и форм. Клиентский код выполняется на компьютере пользователя. Вызов клиентских процедур с сервера невозможен технически, так как сервер «не знает», какому именно пользователю и в какое окно нужно вывести сообщение, и не имеет доступа к программным интерфейсам операционной системы пользователя.
Рассмотрим ситуацию, возникшую в теме: автор создал два модуля — МодулЭльКлиент и МодулЭльСервер. Ошибка возникала по двум причинам:
МодулЭльКлиент внутри кода МодулЭльСервер.Выясним причину, по которой модуль может быть «не виден» в коде. Проверим свойства ваших модулей в конфигураторе:
Для серверного модуля (МодулЭльСервер):
Для клиентского модуля (МодулЭльКлиент):
Поскольку сервер не может сам «толкнуть» клиента (без использования Системы взаимодействия), нам нужно заставить клиента периодически «спрашивать» сервер о наличии новых данных. Для этого используем метод ПодключитьОбработчикОжидания.
Разберем важные требования к этому методу, согласно синтакс-помощнику:
Экспорт).Посмотрим на пример правильной инициализации в модуле управляемого приложения или в форме:
Процедура ПриНачалеРаботыСистемы()
// Подключаем проверку каждые 120 секунд (2 минуты)
ПодключитьОбработчикОжидания("ПроверитьНовыеЗаказыДляМенеджера", 120);
КонецПроцедуры
Теперь создадим алгоритм, который будет работать правильно. Вместо того чтобы пытаться вызвать клиентское оповещение с сервера, мы сделаем наоборот: клиентская процедура будет вызывать серверную функцию, получать результат и показывать его пользователю.
Проанализируем код в серверном модуле МодулЭльСервер:
// Функция возвращает массив ссылок на новые заказы
Функция ПолучитьСписокОткрытыхЗаказов() Экспорт
МассивЗаказов = Новый Массив;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЗаказКлиента.Ссылка КАК Ссылка
|ИЗ
| Документ.ЗаказКлиента КАК ЗаказКлиента
|ГДЕ
| ЗаказКлиента.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказов.Открыт)";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
МассивЗаказов.Добавить(Выборка.Ссылка);
КонецЦикла;
Возврат МассивЗаказов;
КонецФункции
Теперь реализуем клиентскую часть в модуле МодулЭльКлиент или модуле управляемого приложения:
Процедура ПроверитьНовыеЗаказыДляМенеджера() Экспорт
// Вызываем серверную функцию для получения данных
СписокЗаказов = МодулЭльСервер.ПолучитьСписокОткрытыхЗаказов();
Для Каждого ТекущийЗаказ Из СписокЗаказов Цикл
// Формируем текст и навигационную ссылку для интерактивности
ТекстОповещения = "Поступил новый открытый заказ!";
НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(ТекущийЗаказ);
// Показываем всплывающее окно
ПоказатьОповещениеПользователя(
"Внимание!",
НавигационнаяСсылка,
"Заказ №" + ТекущийЗаказ.Номер,
БиблиотекаКартинок.Важное);
КонецЦикла;
КонецПроцедуры
В тексте обсуждения автор спрашивал, можно ли сделать так, чтобы пользователь кликнул на сообщение и открылся документ. Использование метода ПоказатьОповещениеПользователя — это идеальное решение.
Разберем подробнее его параметры:
Важный момент: чтобы сформировать ссылку, используйте функцию ПолучитьНавигационнуюСсылку(СсылкаНаОбъект). Это преобразует ссылку на документ в строковый формат, понятный платформе для перехода.
Выясним, как сделать систему оповещений более легкой. Если у вас в базе работает много пользователей, и каждый из них каждые 2 минуты будет запускать тяжелый запрос к таблице заказов, это может создать избыточную нагрузку на сервер БД.
Рекомендуем рассмотреть следующие улучшения:
ОчередьУведомлений).СистемуВзаимодействия. Она позволяет серверу отправлять Push-уведомления клиенту мгновенно через механизм СообщенияСистемыВзаимодействия, что полностью избавляет от необходимости использовать таймеры и лишние запросы.Таким образом, мы выяснили, что основная ошибка заключалась в попытке смешивания контекстов. Следуя правилу "Клиент запрашивает — Сервер отвечает", вы сможете построить надежную и функциональную систему оповещений в любой конфигурации 1С.