Каждый разработчик 1С рано или поздно сталкивается с типичной задачей автоматизации: менеджеры компании ежедневно выполняют монотонные, рутинные операции. Например, открывают документ «Реестр платежей», выбирают организацию, открывают форму подбора, настраивают сложные фильтры, нажимают кнопку поиска, переносят результаты в документ, записывают его и проводят. Когда таких комбинаций организаций и отборов набирается десяток, ручной труд становится неэффективным и приводит к ошибкам.
Естественное желание разработчика в этом случае — создать «макрос», который бы сам последовательно открывал нужные формы, заполнял их, нажимал кнопки и сохранял результаты. Однако при попытке реализовать это в среде управляемых форм 1С возникает серьезная архитектурная преграда: бизнес-логика (особенно сложные механизмы подбора и заполнения) очень часто жестко «привязана» к контексту конкретной формы. Переносить весь этот код на сервер и переписывать с нуля долго, дорого и чревато ошибками при последующих обновлениях конфигурации.
В этой статье мы подробно рассмотрим четыре практических подхода к решению этой проблемы — от быстрых «компромиссных» вариантов до фундаментально правильного рефакторинга архитектуры, а также разберем, почему популярные инструменты тестирования не подходят для автоматизации реальных бизнес-процессов.
---
Если бюджет проекта или сроки жестко ограничены, и вы категорически не хотите переносить огромные массивы кода из существующих форм на сервер, можно использовать механизм передачи параметров формы. Мы научим форму распознавать, что её открыл не человек, а «робот», выполнять все действия программно и автоматически закрываться.
Разберем этот метод по шагам на примере автоматизации заполнения реестра платежей.
Шаг 1. Инициация процесса из внешней обработки или общего модуля
В нашей управляемой обработке, где менеджер запускает «сценарий», мы программно открываем форму документа и передаем в нее структуру специальных параметров, включая признак автоматического режима:
// Создаем структуру параметров для формы документа
ПараметрыЗапуска = Новый Структура;
ПараметрыЗапуска.Вставить("АвтоЗапускСценария", Истина);
ПараметрыЗапуска.Вставить("Организация", Справочники.Организации.НайтиПоРеквизиту("ИНН", "7701020304"));
ПараметрыЗапуска.Вставить("ИмяНастройкиОтбора", "ПоставщикиУслуг");
// Открываем форму документа, передавая параметры
ОткрытьФорму("Документ.РеестрПлатежей.ФормаОбъекта", ПараметрыЗапуска);
Шаг 2. Обработка параметров внутри формы документа
В модуле формы документа РеестрПлатежей в обработчиках событий мы должны перехватить переданные параметры. На сервере в ПриСозданииНаСервере мы заполняем реквизиты, а на клиенте в ПриОткрытии запускаем интерактивные действия, которые требуют клиентского контекста:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверяем, запущен ли автоматический сценарий
Если Параметры.Свойство("АвтоЗапускСценария") И Параметры.АвтоЗапускСценария Тогда
// Заполняем основные реквизиты на сервере без участия пользователя
Объект.Организация = Параметры.Организация;
Объект.Дата = ТекущаяДатаСеанса();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Если Параметры.Свойство("АвтоЗапускСценария") И Параметры.АвтоЗапускСценария Тогда
// Подключаем обработчик ожидания, чтобы дать форме полностью инициализироваться на клиенте
ПодключитьОбработчикОжидания("ВыполнитьАвтоматическийПодбор", 0.1, Истина);
КонецЕсли;
КонецПроцедуры
Шаг 3. Имитация действий пользователя на клиенте
В процедуре-обработчике ожидания мы вызываем те самые экспортные методы формы подбора или заполнения, которые обычно нажимает пользователь. В завершение мы записываем документ и закрываем форму:
&НаКлиенте
Процедура ВыполнитьАвтоматическийПодбор()
// Имитируем открытие формы подбора с переданной настройкой отбора
ПараметрыПодбора = Новый Структура;
ПараметрыПодбора.Вставить("РежимВыбора", Истина);
ПараметрыПодбора.Вставить("ФильтрПоставщиков", Параметры.ИмяНастройкиОтбора);
// Получаем форму подбора
ФормаПодбора = ПолучитьФорму("Документ.РеестрПлатежей.ФормаПодбора", ПараметрыПодбора, ЭтаФорма);
// Вызываем экспортный метод формы подбора, выполняющий заполнение данных
ФормаПодбора.ВыполнитьПоискДокументовПоНастройкам();
// Переносим данные в наш документ (имитируем нажатие кнопки "Перенести")
// Предположим, что в форме подбора есть экспортный метод получения результатов
ПодобранныеСтроки = ФормаПодбора.ПолучитьРезультатыПодбора();
ЗаполнитьТабличнуюЧастьНаКлиенте(ПодобранныеСтроки);
// Записываем документ и закрываем его форму
Если Записать() Тогда
ПоказатьОповещениеПользователя("Успех", , "Реестр платежей заполнен автоматически!");
КонецЕсли;
Закрыть();
КонецПроцедуры
Этот подход позволяет избежать дублирования сложного кода поиска и подбора, поскольку мы используем те же процедуры, что и пользователь при ручной работе. Однако у этого метода есть огромный недостаток: интерактивное открытие окон на экране пользователя замедляет работу, мерцает перед глазами и делает невозможным фоновое выполнение задачи (например, по расписанию ночью на сервере).
---
Любой опытный архитектор 1С скажет вам, что привязка бизнес-логики к экранным формам — это технический долг, который рано или поздно приведет к серьезным проблемам поддержки. Если логика подбора документов завязана на форму, вы никогда не сможете выполнить эту операцию в фоновом задании на сервере без участия пользователя.
Проанализируем правильный путь решения проблемы: отделение визуального интерфейса от алгоритмов обработки данных.
Шаг 1. Создание серверного общего модуля
Создадим общий модуль с именем РеестрПлатежейСервер со свойствами Сервер, Вызов сервера. Перенесем в него алгоритм поиска и подбора документов, очистив его от любых клиентских вызовов (таких как Предупреждение, Вопрос, ОткрытьФорму).
// В общем модуле РеестрПлатежейСервер
Функция ПолучитьДокументыДляРеестра(ПараметрыОтбора) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЗаявкаНаРасходованиеСредств.Ссылка КАК Ссылка,
| ЗаявкаНаРасходованиеСредств.СуммаДокумента КАК Сумма
|ИЗ
| Документ.ЗаявкаНаРасходованиеСредств КАК ЗаявкаНаРасходованиеСредств
|ГДЕ
| ЗаявкаНаРасходованиеСредств.Организация = &Организация
| И ЗаявкаНаРасходованиеСредств.Проведен = ИСТИНА
| И ЗаявкаНаРасходованиеСредств.Оплачено = ЛОЖЬ";
Запрос.УстановитьПараметр("Организация", ПараметрыОтбора.Организация);
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
Процедура ЗаполнитьИЗаписатьРеестр(Знач Организация, Знач НастройкиОтбора) Экспорт
НовыйРеестр = Документы.РеестрПлатежей.СоздатьДокумент();
НовыйРеестр.Дата = ТекущаяДата();
НовыйРеестр.Организация = Организация;
ПараметрыОтбора = Новый Структура("Организация", Организация);
ТаблицаПодобраныхДанных = ПолучитьДокументыДляРеестра(ПараметрыОтбора);
НовыйРеестр.Заявки.Загрузить(ТаблицаПодобраныхДанных);
Попытка
НовыйРеестр.Записать(РежимЗаписиДокумента.Проведение);
Исключение
ЗаписьЖурналаРегистрации("Автоматизация.ЗаполнениеРеестра",
УровеньЖурналаРегистрации.Ошибка, , , ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
Шаг 2. Использование общего модуля в интерактивной форме
Теперь форма подбора документа также должна использовать этот общий модуль. Код формы подбора существенно сократится и станет чище:
&НаСервере
Процедура ВыполнитьПоискНаФорме()
ПараметрыОтбора = Новый Структура("Организация", Объект.Организация);
// Вызываем единый метод бизнес-логики
РезультатТаблица = РеестрПлатежейСервер.ПолучитьДокументыДляРеестра(ПараметрыОтбора);
// Отображаем результат на форме в динамическом списке или таблице значений
ЗначениеВРеквизитФормы(РезультатТаблица, "СписокПодобранныхДокументов");
КонецПроцедуры
Шаг 3. Запуск автоматического фонового процесса
Теперь, когда бизнес-логика полностью отделена от интерфейса, вы можете легко настроить автоматическое регламентное задание, которое будет выполняться на сервере по расписанию каждую ночь, вообще не открывая никаких клиентских приложений 1С:
// Процедура регламентного задания
Процедура ВыполнитьАвтоматическуюОбработкуРеестров() Экспорт
Организация = Справочники.Организации.НайтиПоРеквизиту("ИНН", "7701020304");
РеестрПлатежейСервер.ЗаполнитьИЗаписатьРеестр(Организация, "СтандартнаяНастройка");
КонецПроцедуры
Да, этот подход требует времени на рефакторинг. Но вы навсегда закроете технический долг, избавитесь от дублирования кода, а система станет масштабируемой и стабильной.
---
В процессе обсуждения часто возникает идея использовать механизмы сценарного тестирования платформы 1С для регулярного выполнения рабочих задач пользователей. Платформа действительно предоставляет мощный инструментарий автоматизации UI через объект ТестовоеПриложение.
Рассмотрим, как выглядит концепция сценарного автоматического тестирования:
/TestManager)./TestClient), в котором открывается рабочая база.Пример кода сценария тестирования:
// Пример управления UI через менеджер тестирования
Процедура ВыполнитьСценарийТестирования(ТестовоеПриложение)
// Имитируем нажатие кнопки меню для открытия реестра платежей
РеестрыФорма = ТестовоеПриложение.НайтиОбъект(Тип("ТестируемоеОкноПриложения"), "Реестры платежей");
РеестрыФорма.Активизировать();
// Нажимаем кнопку "Создать"
КнопкаСоздать = РеестрыФорма.НайтиОбъект(Тип("ТестируемаяКнопкаФормы"), "Создать");
КнопкаСоздать.Нажать();
// Находим поле ввода организации и заполняем его
ПолеОрганизация = ТестовоеПриложение.НайтиОбъект(Тип("ТестируемоеПолеФормы"), "Организация");
ПолеОрганизация.ВвестиТекст("ООО Ромашка");
КонецПроцедуры
Почему этот метод категорически не подходит для автоматизации бизнес-процессов в продакшене?
---
Если ваша конфигурация 1С находится на строгой поддержке вендора (ее нельзя изменять ни при каких обстоятельствах), либо если цепочка действий менеджера выходит далеко за рамки 1С (например, нужно взять данные из Excel на рабочем столе, зайти в 1С, провести документы, зайти на сайт банка и отправить платежку), идеальным решением становится использование технологий RPA (Роботизация процессов).
Специализированные программные роботы (например, PIX RPA или Primo RPA) работают на уровне операционной системы. Они могут:
Однако внедрение RPA требует покупки сторонних лицензий и настройки отдельной инфраструктуры, поэтому данный вариант целесообразен только при комплексной автоматизации сложных межсистемных процессов.
---
Проанализируем все рассмотренные варианты по ключевым критериям, чтобы вы могли принять взвешенное решение:
Вывод очевиден: инвестируйте время в правильное разделение UI и бизнес-логики (рефакторинг). Это позволит вам не только решить текущую проблему рутины менеджеров, но и заложит прочный фундамент для будущих интеграций, мобильных приложений и фоновых процессов вашей информационной системы.