Как запустить обработку или открыть форму на клиенте по расписанию в 1С?

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

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

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

Почему нельзя просто вызвать клиентскую процедуру с сервера?

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

Клиентский сеанс всегда выступает инициатором запроса к серверу, но не наоборот. Чтобы обойти это ограничение, нам необходимо настроить механизм на стороне самого клиента, который будет периодически обращаться к серверу за задачами или реагировать на внешние события.

---

Вариант 1. Использование встроенной подсистемы БСП «Напоминания пользователя»

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

Суть метода заключается в том, что регламентное задание на сервере по своему расписанию генерирует записи в специальном регистре сведений, а стандартные механизмы БСП на клиенте сами считывают эти записи и выводят интерактивное окно пользователю.

Рассмотрим пример кода, который можно выполнять в серверном регламентном задании для создания напоминания конкретному пользователю:


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

    МенеджерЗаписи = РегистрыСведений.НапоминанияПользователя.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.Пользователь = ПользовательСсылка;
    МенеджерЗаписи.ВремяСобытия = ВремяСрабатывания;
    МенеджерЗаписи.СрокНапоминания = ВремяСрабатывания;
    МенеджерЗаписи.Описание = ТекстНапоминания;
    МенеджерЗаписи.СпособУстановкиВремениНапоминания = Перечисления.СпособыУстановкиВремениНапоминания.ВУказанноеВремя;
    
    // Если нужно, чтобы при нажатии на напоминание открывалась конкретная форма или документ:
    МенеджерЗаписи.Источник = СсылкаНаОбъект; 
    
    МенеджерЗаписи.Записать();

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

Как это работает для пользователя: В назначенное время у пользователя всплывает стандартное системное окно со списком напоминаний. При двойном клике на строку напоминания автоматически открывается форма привязанного объекта (например, нужная нам обработка или документ). Конфигурация при этом остается на полной поддержке.

---

Вариант 2. Глобальный обработчик ожидания через расширение конфигурации

Если вам требуется не просто показать стандартное напоминание, а выполнить сложный алгоритм на клиенте или принудительно открыть кастомное диалоговое окно (без участия пользователя), оптимальным решением будет использование Расширения конфигурации.

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

Разберем по шагам процесс реализации данного сценария:

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

Пропишем следующий код в модуле управляемого приложения расширения:


&После("ПриНачалеРаботыСистемы")
Процедура Расш_ПриНачалеРаботыСистемы()
    
    // Подключаем обработчик ожидания, который будет срабатывать каждые 60 секунд.
    // Метод должен быть расположен в неглобальном общем модуле на клиенте.
    ИнтервалПовтора = 60; 
    ПодключитьОбработчикОжидания("Расш_КлиентскийМодуль.ПроверитьНеобходимостьОткрытияФормы", ИнтервалПовтора, Ложь);
    
КонецПроцедуры

Теперь создадим в расширении общий модуль с именем Расш_КлиентскийМодуль. В свойствах модуля обязательно установим флаги Клиент (управляемое приложение). Код модуля будет выглядеть следующим образом:


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

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

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

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

---

Вариант 3. Использование Системы взаимодействия (Мгновенный PUSH-вызов)

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

Система взаимодействия работает по протоколу WebSockets, что позволяет серверу отправлять сообщения (сигналы) подключенным клиентам в режиме реального времени.

Рассмотрим сценарий реализации мгновенного открытия формы:

  1. При старте системы клиент подписывается на получение сообщений в служебном невидимом обсуждении.
  2. Серверное регламентное задание при наступлении события отправляет сообщение в это обсуждение.
  3. Клиент мгновенно «ловит» событие на своей стороне и открывает форму.

Пример клиентского кода в расширении для подключения обработчика сообщений:


&После("ПриНачалеРаботыСистемы")
Процедура ПодключитьСистемуВзаимодействия()
    
    // Начинаем прослушивание сообщений Системы взаимодействия
    Обработчик = Новый ОписаниеОповещения("ПолученоСлужебноеСообщение", ЭтотОбъект);
    СистемаВзаимодействия.НачатьПодключениеОбработчикаНовыхСообщений(Обработчик);
    
КонецПроцедуры

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

Пример серверного кода (например, внутри регламентного задания), который инициирует открытие формы у конкретного пользователя:


Процедура ОтправитьСигналНаКлиент(ЦелевойПользователь, ТекстДанных) Экспорт

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

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

Этот способ является наиболее технологичным и современным, поскольку он сводит к нулю лишнюю нагрузку на СУБД, возникающую при классических ежеминутных опросах.

---

Вариант 4. Запуск через внешнюю обработку при старте сеанса

В случаях, когда использование расширений по каким-то причинам жестко ограничено политикой безопасности компании, можно прибегнуть к возможностям запуска внешних обработок на стороне клиента.

Для этого используется штатный механизм БСП «Дополнительные отчеты и обработки» либо параметры командной строки при запуске 1С. Мы можем прописать запуск специальной внешней обработки при старте системы:

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

---

Резюме и рекомендации

Каждый из рассмотренных методов имеет свои преимущества в зависимости от условий задачи:

← На главную