В процессе разработки на платформе 1С часто возникает ситуация, когда объемная бизнес-логика уже написана в клиентских модулях или формах. Если бизнес требует автоматизировать выполнение этих действий по расписанию (например, обновление данных, загрузка прайсов или формирование сложных отчетов), разработчик сталкивается с проблемой: регламентные задания 1С выполняются строго на сервере. Перенос огромного блока «клиентского» кода на сервер может занять недели и потребовать последующего двойного сопровождения. В этой статье мы разберем, как решить эту задачу с помощью проверенных практических методов, не прибегая к полному рефакторингу системы.
Самый надежный способ запустить клиентский код — это имитировать запуск реального сеанса пользователя. Для этого мы воспользуемся планировщиком задач операционной системы и ключами запуска 1С. Рассмотрим этот процесс по шагам.
Основная идея заключается в использовании ключа /Execute для запуска внешней обработки или ключа /C для передачи параметра в конфигурацию. Проанализируем, как это реализовать программно. В модуле управляемого приложения найдем процедуру ПриНачалеРаботыСистемы и добавим обработку входящего параметра.
Процедура ПриНачалеРаботыСистемы()
ПараметрыЗапускаСтрока = ПараметрыСеанса.ПараметрЗапуска;
Если Найти(ПараметрыЗапускаСтрока, "ЗапуститьОбновлениеДанных") > 0 Тогда
// Вызываем нашу клиентскую процедуру из общего модуля
Обработки.ОбновлениеДилерскихДанных.ОбновитьВсе();
// После выполнения закрываем сеанс, чтобы не занимать лицензию
ЗавершитьРаботуСистемы(Ложь);
КонецЕсли;
КонецПроцедуры
Теперь нам необходимо настроить запуск этого сеанса в планировщике задач Windows. Создадим задачу, в которой укажем путь к исполняемому файлу 1С и параметры подключения. Команда будет выглядеть примерно так:
"C:\Program Files\1cv8\common\1cestart.exe" ENTERPRISE /F "ПутьКБазе" /N "RobotUser" /P "Password" /C "ЗапуститьОбновлениеДанных"
Важный нюанс: Для стабильной работы такого «робота» на сервере рекомендуется настроить AutoLogon для технической учетной записи. Это связано с тем, что для выполнения клиентского кода 1С требуется наличие графической оболочки (сессии пользователя). Если сессия не будет активна, некоторые функции (особенно связанные с открытием форм или внешними компонентами) могут отработать некорректно.
Если в компании есть выделенный компьютер (например, монитор на складе или серверный терминал), где сеанс 1С запущен круглосуточно, мы можем использовать встроенный механизм 1С — ПодключитьОбработчикОжидания. Этот метод позволяет запускать процедуру через определенные интервалы времени непосредственно в контексте клиента.
Разберем реализацию в модуле управляемого приложения. Нам нужно инициировать обработчик при старте системы, но только для конкретного пользователя, чтобы не создавать нагрузку у всех сотрудников сразу.
Процедура ПриНачалеРаботыСистемы()
// Проверяем, что это наш "сервисный" пользователь
Если ПользователиИнформационнойБазы.ТекущийПользователь().Имя = "ServiceRobot" Тогда
// Подключаем процедуру, которая будет срабатывать раз в час (3600 секунд)
ПодключитьОбработчикОжидания("ВыполнитьКлиентскоеОбновление", 3600);
КонецЕсли;
КонецПроцедуры
Процедура ВыполнитьКлиентскоеОбновление() Экспорт
// Здесь вызывается основной клиентский код
МойКлиентскийМодуль.ОбработатьДанные();
КонецПроцедуры
Преимущество этого метода в том, что нам не нужно постоянно открывать и закрывать приложение 1С, тратя время на инициализацию и лицензии. Однако помните, что процедура ВыполнитьКлиентскоеОбновление должна быть описана в модуле управляемого приложения или в общем модуле с флагом Клиент.
Рассмотрим более современный и элегантный подход, который позволяет избежать постоянных опросов базы данных. Если в вашей базе настроена Система взаимодействия, мы можем использовать её для передачи команд от серверного регламентного задания к конкретному клиентскому приложению.
Выясним причину, почему это эффективно: серверное регламентное задание работает по расписанию идеально, но оно не «видит» клиентский контекст. Мы можем заставить сервер отправить «сообщение-команду» клиенту. Посмотрим на пример кода для отправки сообщения с сервера:
// Код в серверном регламентном задании
Сообщение = СистемаВзаимодействия.СоздатьСообщение(НужноеОбсуждение);
Сообщение.Текст = "START_UPDATE";
Сообщение.Записать();
На стороне клиента нам нужно подписаться на получение сообщения. В модуле управляемого приложения проанализируем входящий текст и запустим код:
Процедура ПриНачалеРаботыСистемы()
СистемаВзаимодействия.ПодключитьОбработчикПолученияСообщения(
Новый ОписаниеОповещения("ОбработкаКомандыОтСервера", ЭтотОбъект)
);
КонецПроцедуры
Процедура ОбработкаКомандыОтСервера(Сообщение, ДополнительныеПараметры) Экспорт
Если Сообщение.Текст = "START_UPDATE" Тогда
// Запускаем тяжелый клиентский код
ВыполнитьОбновлениеИнтерфейса();
КонецЕсли;
КонецПроцедуры
Этот метод позволяет гибко управлять нагрузкой. Например, вы можете отправить команду сразу всем подключенным пользователям или только одному «роботу».
Бывают случаи, когда код настолько сильно завязан на логику конкретных экранных форм, что просто вызвать процедуру из общего модуля недостаточно. В таких ситуациях мы можем применить механизм автоматизированного тестирования.
Разберем по шагам, как это работает:
/TestClient. Он будет выступать в роли исполнителя./TestManager.Этот метод считается экстремальным, но он незаменим, когда код «зашит» внутри обработчиков событий формы, к которым нет прямого доступа извне. Проанализируем пример скрипта для Менеджера тестирования:
// В сеансе Тест-менеджера
ТестируемоеПриложение.Подключить(8080); // Порт тест-клиента
Окно = ТестируемоеПриложение.НайтиОбъект(Тип("ТестируемоеОкноКлиентскогоПриложения"), "ФормаДокумента");
Кнопка = Окно.НайтиОбъект(Тип("ТестируемаяКнопкаФормы"), "КнопкаОбновить");
Кнопка.Нажать();
Если вам нужно управлять запуском извне системы (например, из скрипта Python или PowerShell), можно использовать V83.Application через COM-интерфейс. В отличие от V83.COMConnector, объект Application запускает полноценное визуальное приложение.
Посмотрим на пример логики внешнего скрипта:
1C.Application.Connect.Execute или обращение к экспортным процедурам глобального модуля инициирует выполнение нужного кода.Это позволяет реализовать сложные сценарии обработки ошибок, когда скрипт может принудительно «убить» зависший процесс 1С через Task Manager и запустить его заново, обеспечивая максимальную отказоустойчивость.
Подводя итог, проанализируем, какой метод лучше выбрать в вашей ситуации:
/Execute или /C.ПодключитьОбработчикОжидания.Важно помнить: использование «костылей» для запуска клиентского кода — это временная мера. В долгосрочной перспективе старайтесь выносить тяжелую бизнес-логику в общие модули с флагом Сервер, чтобы система работала стабильно и предсказуемо в рамках штатных регламентных заданий 1С.