Как реализовать систему оповещения активных пользователей в 1С 8.2 на обычных формах

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей IT и автоматизация бизнеса
← На главную

В процессе сопровождения информационных систем на базе 1С 8.2 (особенно в конфигурации "Управление торговлей" 10.3) часто возникает задача оперативного информирования пользователей. Обычное использование функции Сообщить() не подходит, так как оно выводит текст в окно сообщений, которое пользователь может не заметить, а при открытии документа или выполнении регламентного действия требуется привлечь внимание всех или конкретных участников процесса. Разберем наиболее эффективные методы реализации такой системы, избегая "спама" и лишней нагрузки на сервер.

Метод 1: Использование регистра сведений и обработчика ожидания

Проанализируем самый надежный и гибкий способ — создание "очереди сообщений" внутри базы данных. Этот метод позволяет не только отправлять текст, но и контролировать факт прочтения сообщения пользователем. Суть заключается в том, что информация записывается в специальную таблицу, а клиентское приложение периодически "опрашивает" эту таблицу на наличие новых записей.

Для начала создадим новый Регистр сведений, назовем его ОчередьСообщений. Нам понадобятся следующие измерения и ресурсы:

  1. Получатель (Измерение, тип: СправочникСсылка.Пользователи) — кому предназначено сообщение.
  2. ДатаСообщения (Измерение, тип: Дата) — для сортировки и уникальности.
  3. ТекстСообщения (Ресурс, тип: Строка) — собственно содержание уведомления.
  4. Прочитано (Ресурс, тип: Булево) — флаг, указывающий, видел ли пользователь это окно.

Теперь рассмотрим программную часть. Нам необходимо настроить периодическую проверку в глобальном модуле или модуле приложения. Разберем по шагам, как это реализовать через ПодключитьОбработчикОжидания.

В модуле обычного приложения (или в форме, которая всегда открыта) пропишем инициализацию:


Процедура ПриНачалеРаботыСистемы()
    // Интервал в секундах, например, каждые 60 секунд
    ПодключитьОбработчикОжидания("ПроверитьНовыеСообщения", 60);
КонецПроцедуры

Далее создадим саму процедуру проверки. Важно сделать запрос максимально "легким", чтобы он не блокировал работу пользователя и не создавал нагрузку на SQL-сервер при одновременном обращении 100 человек.


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

    Запрос.УстановитьПараметр("ТекущийПользователь", ПараметрыСеанса.ТекущийПользователь);
    
    Результат = Запрос.Выполнить();
    Если Не Результат.Пустой() Тогда
        Выборка = Результат.Выбрать();
        Выборка.Следующая();
        
        // Выводим сообщение пользователю
        Предупреждение(Выборка.ТекстСообщения, 10, "Важное уведомление!");
        
        // Помечаем сообщение как прочитанное
        МенеджерЗаписи = РегистрыСведений.ОчередьСообщений.СоздатьМенеджерЗаписи();
        МенеджерЗаписи.Получатель = ПараметрыСеанса.ТекущийПользователь;
        МенеджерЗаписи.ДатаСообщения = Выборка.ДатаСообщения;
        МенеджерЗаписи.Прочитать();
        МенеджерЗаписи.Прочитано = Истина;
        МенеджерЗаписи.Записать();
    КонецЕсли;
КонецПроцедуры

Важный момент: Мы используем Предупреждение() с таймаутом (10 секунд), чтобы модальное окно не заблокировало работу системы, если пользователь отошел от компьютера.

Метод 2: Механизм задач и бизнес-процессов

Как упоминалось в обсуждении на форуме, в типовых решениях (например, ЗУП 2.5 или УПП) уже есть встроенные механизмы задач. Если в вашей конфигурации включено использование бизнес-процессов, логичнее использовать объект Задача.

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

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


Процедура ПриОткрытии()
    Если ЭтоНовый() Тогда 
        Возврат; 
    КонецЕсли;
    
    // Допустим, мы хотим уведомить автора, что его документ открыт специалистом
    НоваяЗадача = Задачи.ЗадачиПользователей.СоздатьЗадачу();
    НоваяЗадача.Наименование = "Ваш документ " + Строка(Ссылка) + " взят в работу";
    НоваяЗадача.Исполнитель = ЭтотОбъект.Автор; // Указываем получателя
    НоваяЗадача.Дата = ТекущаяДата();
    НоваяЗадача.Записать();
КонецПроцедуры

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

Метод 3: Использование системных уведомлений Windows (через COM-объекты)

Если требуется вывести сообщение поверх всех окон, даже если 1С свернута, можно воспользоваться возможностями операционной системы. Рассмотрим пример работы с объектом WScript.Shell. Это позволит вывести всплывающее окно средствами Windows.


Процедура ОповеститьЧерезWindows(ТекстСообщения)
    Попытка
        WshShell = Новый COMОбъект("WScript.Shell");
        // Параметры Popup: Текст, ВремяОтображения(сек), Заголовок, ТипИконки
        WshShell.Popup(ТекстСообщения, 5, "Сообщение от 1С", 64);
    Исключение
        // Если COM-объект недоступен, откатываемся к стандартному методу
        Сообщить(ТекстСообщения);
    КонецПопытки;
КонецПроцедуры

Преимущество этого метода в том, что он не создает модальности внутри 1С, которая могла бы прервать выполнение фоновых алгоритмов или расчетов.

Рекомендации по оптимизации системы оповещений

Рассмотрим ситуацию, когда в базе одновременно работают более 100 пользователей. Постоянные запросы к базе данных могут снизить производительность. Чтобы этого избежать, проанализируем следующие советы:

  1. Индексация: Обязательно убедитесь, что поля Получатель и Прочитано в регистре сведений являются индексируемыми. Это позволит SQL-серверу мгновенно находить нужные записи.
  2. Разделение по важности: Не отправляйте каждое событие всем пользователям. Как справедливо заметили на форуме, избыточный "спам" приводит к тому, что сотрудники начинают игнорировать уведомления. Реализуйте в регистре поле УровеньВажности и выводите окна только для "Критичных" событий.
  3. Использование Параметров Сеанса: Если вам нужно передать очень короткий сигнал, можно использовать параметры сеанса, но помните, что они индивидуальны для каждого пользователя. Для широковещательной рассылки (всем сразу) лучше всего подходит именно Регистр сведений.
  4. Автоматическая очистка: Не забывайте удалять или архивировать старые прочитанные сообщения из регистра. Раз в неделю запускайте регламентное задание, которое очищает записи старше месяца, чтобы таблица не разрасталась до гигантских размеров.

Выясним, какой метод выбрать. Если вам нужна простота и надежность в УТ 10.3 — выбирайте Метод 1 (Регистр сведений + Обработчик ожидания). Если ваша конфигурация уже активно использует задачи — интегрируйтесь в **Метод 2**. Для экстренных уведомлений, которые нельзя пропустить, используйте **Метод 3**.

Разберем типичную ошибку: попытку вызвать Предупреждение() прямо в коде модуля документа без проверки контекста. Помните, что в 1С 8.2 на обычных формах программное открытие формы или вывод окна из серверного контекста может привести к ошибке. Всегда проверяйте наличие доступного клиентского интерфейса.

← На главную