При разработке внешних обработок в среде 1С:Предприятие программисты часто сталкиваются с ситуацией, когда функционал, изначально написанный для интерактивной работы пользователя, требуется запускать автоматически по расписанию. В этот момент возникает типичная ошибка: попытка вызвать процедуры модуля формы из модуля объекта или напрямую из регламентного задания. Давайте подробно разберем, почему это технически невозможно и как правильно перестроить архитектуру решения, чтобы код оставался универсальным и легко поддерживаемым.
Для начала проанализируем ситуацию с точки зрения архитектуры платформы. Когда мы запускаем регламентное или фоновое задание, система создает на сервере отдельный сеанс. У этого сеанса полностью отсутствует графический интерфейс. Это означает, что объектов типа УправляемаяФорма в данном контексте просто не существует.
Рассмотрим ключевые причины ограничений:
ПолучитьФорму(), система выдаст ошибку, так как на сервере нет «клиента», который мог бы отрисовать или инициализировать эту форму.Выясним причину, по которой разработчики пытаются обращаться к форме: часто это нежелание «плодить код» и дублировать алгоритмы. Чтобы избежать дублирования, разберем правильный паттерн разработки. Рассмотрим по шагам, как подготовить вашу обработку к работе в двух режимах (вручную и в фоне).
Шаг 1. Вынос алгоритма в модуль объекта.
Вместо того чтобы писать логику в процедуре &НаКлиенте Процедура ВыполнитьДействие(), мы создаем экспортную процедуру в модуле объекта. Проанализируем пример кода в модуле объекта:
// В модуле объекта
Процедура ВыполнитьОсновнуюЛогику(ПараметрыЗапуска) Экспорт
// Здесь размещаем весь тяжелый код:
// запросы, переборы выборок, заполнение таблиц
Для Каждого Строка Из ПараметрыЗапуска.Данные Цикл
// Обработка данных
КонецЦикла;
КонецПроцедуры
Шаг 2. Вызов из модуля формы.
Теперь в модуле формы нам достаточно просто вызвать этот метод. Для этого мы преобразуем форму в объект. Посмотрим на пример:
&НаСервере
Процедура ВыполнитьНаСервере()
// Конвертируем данные формы в объект обработки
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
// Подготавливаем параметры
Параметры = Новый Структура("Данные", Объект.СписокТоваров);
// Вызываем общую логику
ОбработкаОбъект.ВыполнитьОсновнуюЛогику(Параметры);
// Если нужно вернуть изменения в форму
ЗначениеВРеквизитФормы(ОбработкаОбъект, "Объект");
КонецПроцедуры
Теперь, когда основная логика находится в модуле объекта, мы можем легко запустить ее из любого места на сервере, в том числе из регламентного задания, не обращаясь к форме. Рассмотрим программный код для фонового запуска:
// В общем модуле или модуле регламентного задания
ПутьКФайлу = "C:\ExternalProc\MyProcessing.epf";
Обработка = ВнешниеОбработки.Создать(ПутьКФайлу, Ложь);
Параметры = Новый Структура;
Параметры.Вставить("Данные", ПолучитьДанныеДляОбработки());
// Прямой вызов экспортной процедуры модуля объекта
Обработка.ВыполнитьОсновнуюЛогику(Параметры);
Таким образом, мы добились главного: код написан один раз, но доступен и пользователю через кнопку на форме, и системе через регламентное задание.
Если ваша конфигурация использует Библиотеку стандартных подсистем (БСП), задача упрощается еще сильнее. Разберем, как это работает через механизм дополнительных отчетов и обработок. В этом случае нам не нужно создавать свои регламентные задания в конфигураторе.
Достаточно в модуле объекта реализовать экспортную функцию СведенияОВнешнейОбработке() и процедуру ВыполнитьКоманду(). Посмотрим на структуру процедуры ВыполнитьКоманду:
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполненияКоманды) Экспорт
Если ИдентификаторКоманды = "ОсновноеДействие" Тогда
// Вызываем нашу универсальную процедуру
ВыполнитьОсновнуюЛогику(ПараметрыВыполненияКоманды);
КонецЕсли;
КонецПроцедуры
В интерфейсе программы (в справочнике "Дополнительные отчеты и обработки") вы сможете настроить расписание для этой команды. Система сама создаст фоновое задание и вызовет метод модуля объекта, полностью игнорируя форму.
Поскольку автор темы упомянул сложности с отладкой, проанализируем ситуацию. Отладка в модуле формы работает легко, потому что это клиентский сеанс. В фоновом задании отладка по умолчанию может не работать. Чтобы "поймать" выполнение кода в модуле объекта при запуске из фона, выполните следующие действия:
-debug.Если же отладка на сервере невозможна, рекомендуется сначала протестировать логику в обычном сеансе, вызывая метод модуля объекта через небольшую тестовую обработку, и только потом переносить запуск в регламентное задание.
При переносе кода из формы в модуль объекта важно помнить о методах, которые запрещены на сервере и в фоне:
Предупреждение(), Вопрос(), Сообщить() (в фоне сообщение уйдет в журнал регистрации, но пользователь его не увидит).ДиалогВыбораФайла — в фоне нет доступа к файловой системе локального компьютера пользователя. Все файлы должны загружаться из временного хранилища или сетевых папок, доступных серверу.ДанныеФормыСтруктура должны быть преобразованы в обычные Структура или ТаблицаЗначений.Подведем итог: попытка достучаться до формы из фонового режима — это архитектурная ошибка. Правильное решение заключается в выносе бизнес-логики в модуль объекта или общий модуль. Форма в данном случае выступает лишь как один из способов передачи параметров в эту логику. Такой подход делает систему надежной, легкой в тестировании и соответствующей стандартам разработки 1С.