В процессе сопровождения систем на базе 1С часто возникает задача автоматизации рутинных действий. Например, нам нужно, чтобы при запуске системы определенным пользователем (или по расписанию) выполнялась некая обработка: проверка данных, загрузка курсов валют или рассылка уведомлений. При этом крайне важно сохранить конфигурацию на поддержке («на замке») и обеспечить стабильную работу «робота», чтобы он не мешал основному пользователю. Разберем подробно, как это реализовать, используя современные инструменты платформы и Библиотеки стандартных подсистем (БСП).
Если ваша конфигурация построена на БСП (а это почти все современные решения: Бухгалтерия 3.0, УТ 11, ERP), то наиболее правильный путь — использование справочника «Дополнительные отчеты и обработки». Рассмотрим, как подготовить модуль объекта внешней обработки, чтобы система «узнала» ее и позволила запускать по расписанию.
Для начала нам необходимо прописать экспортную функцию СведенияОВнешнейОбработке в модуле объекта. Это своеобразный «паспорт» обработки. Проанализируем пример кода:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиДополнительнаяОбработка();
ПараметрыРегистрации.Наименование = "Робот автоматической проверки";
ПараметрыРегистрации.Версия = "1.0";
ПараметрыРегистрации.БезопасныйРежим = Ложь;
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Запустить робота";
НоваяКоманда.Идентификатор = "ЗапускРобота";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
НоваяКоманда.ПоказыватьОповещение = Истина;
Возврат ПараметрыРегистрации;
КонецФункции
Разберем важный нюанс, упомянутый в обсуждении: разницу между типами команд. Если мы указываем ВызовСерверногоМетода, обработка будет выполняться на сервере без открытия окон. Это идеальный вариант для фонового задания. Если же выбрать ВызовКлиентскогоМетода или ОткрытиеФормы, система попытается открыть интерфейс, что невозможно при работе регламентного задания.
Когда обработка добавлена в справочник «Дополнительные отчеты и обработки», мы можем настроить её запуск по расписанию. Выясним, как это сделать правильно:
Важный момент: Код, который должен выполняться «роботом», необходимо разместить в процедуре ВыполнитьКоманду модуля объекта обработки. Рассмотрим пример структуры:
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполненияКоманды) Экспорт
Если ИдентификаторКоманды = "ЗапускРобота" Тогда
// Здесь логика вашего робота
ВыполнитьТехническиеДействия();
КонецЕсли;
КонецПроцедуры
Часто возникает вопрос: как передать в обработку-робот параметры (например, дату запрета или список складов), если форма при автоматическом запуске не открывается? Рассмотрим использование ХранилищаОбщихНастроек, как советовали эксперты в обсуждении.
Проанализируем ситуацию: нам нужно иметь одну форму для настройки (где пользователь нажимает кнопку «Сохранить») и серверный метод, который эти настройки читает. В модуле формы прописываем сохранение:
&НаКлиенте
Процедура СохранитьНастройкиНажать(Команда)
СтруктураНастроек = Новый Структура;
СтруктураНастроек.Вставить("Склад", Объект.Склад);
СтруктураНастроек.Вставить("ЛимитСуммы", Объект.ЛимитСуммы);
СохранитьНастройкиНаСервере(СтруктураНастроек);
ПоказатьОповещениеПользователя("Успех", , "Настройки робота сохранены");
КонецПроцедуры
&НаСервере
Процедура СохранитьНастройкиНаСервере(СтруктураНастроек)
ХранилищеОбщихНастроек.Сохранить("МойРобот", "НастройкиПоУмолчанию", СтруктураНастроек);
КонецПроцедуры
Теперь в модуле объекта, когда обработка запускается регламентным заданием, мы можем легко их прочитать:
Процедура ВыполнитьТехническиеДействия()
Настройки = ХранилищеОбщихНастроек.Загрузить("МойРобот", "НастройкиПоУмолчанию");
Если Настройки <> Неопределено Тогда
ТекСклад = Настройки.Склад;
// Работаем с параметрами...
КонецЕсли;
КонецПроцедуры
Разберем проблему блокировки: что делать, если один пользователь уже запустил обработку, а система пытается запустить ее повторно? Использование флага (0 или 1) в настройках — самый простой, но ненадежный способ (при аварийном завершении флаг «зависнет» в значении 1).
Рекомендуем использовать механизм Блокировки данных. Проанализируем логику: перед началом работы обработка пытается установить исключительную блокировку на какой-то условный ключ. Если другой сеанс уже держит эту блокировку, вторая попытка вызовет исключение, и мы поймем, что «робот» уже занят.
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Справочник.Номенклатура"); // Можно использовать любой справочник
ЭлементБлокировки.УстановитьЗначение("Ссылка", Справочники.Номенклатура.ПустаяСсылка());
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
Попытка
Блокировка.Заблокировать();
// Если код дошел сюда — мы «захватили» право на запуск
Исключение
Возврат; // Кто-то другой уже работает
КонецПопытки;
Если же задача стоит запустить обработку именно «в руках» у пользователя при старте его компьютера, можно использовать параметры запуска 1С. Рассмотрим этот вариант подробнее. В ярлыке запуска 1С после пути к базе можно добавить ключ /Execute.
Пример: "C:\Program Files\1cv8\common\1cestart.exe" ENTERPRISE /F "C:\Bases\MyBase" /Execute "C:\Scripts\MyRobot.epf"
В этом случае при открытии 1С система сразу предложит запустить внешнюю обработку. Однако у этого метода есть минус: пользователю может потребоваться подтверждение безопасности. Чтобы избежать лишних вопросов, лучше использовать расширение конфигурации, которое в событии ПриНачалеРаботыСистемы будет программно вызывать нужную обработку из справочника БСП.
Проанализируем выгоды такого подхода: конфигурация остается типовой, расширение не требует снятия с поддержки, а логика запуска полностью контролируется кодом.
Подведем итоги нашего исследования. Для запуска внешних действий в 1С 8.3 наиболее стабильным является следующий алгоритм:
СведенияОВнешнейОбработке.ХранилищеОбщихНастроек или непосредственно в атрибутах справочника БСП.ПоказатьОповещениеПользователя(), который всплывает в углу экрана и не блокирует ввод данных.Помните, что при работе на сервере (в фоновом задании) нельзя использовать функции типа Предупреждение() или Вопрос(). Весь код должен быть строго серверным и автономным. Следуя этим правилам, вы создадите надежного автоматизированного помощника, который будет работать незаметно для пользователей и эффективно для бизнеса.