Перенос функционала из внешней обработки, запускаемой вручную, в автоматическое регламентное задание — стандартная задача для разработчика 1С. Однако часто при этом возникают ситуации, когда код, успешно работающий «по кнопке», отказывается выполняться в фоновом режиме. В этой статье мы подробно разберем, как правильно реализовать выгрузку данных в XML и их отправку на FTP через механизм регламентных заданий, проанализируем типичные ошибки и рассмотрим способы их устранения.
Разберем ситуацию: у нас есть готовая процедура во внешней обработке, которая формирует XML-файл, сохраняет его на диск и отправляет на удаленный сервер. При нажатии кнопки всё работает, но при попытке запуска через регламентное задание файл не появляется. Основная причина кроется в контексте выполнения. Фоновые задания выполняются на стороне сервера под учетной записью службы «Агент сервера 1С:Предприятия» (например, USR1CV8), которая имеет другие права и окружение, нежели ваш текущий пользователь Windows.
Рассмотрим основные факторы, которые необходимо проверить:
Сообщить(), Предупреждение() или Вопрос() в коде регламентного задания недопустимо. На сервере нет интерфейса, и вызов этих функций может привести к аварийному завершению задания.C:\Обмен\) должен быть доступен пользователю, от имени которого запущен сервер 1С.Z:\). Для работы с сетевыми ресурсами необходимо использовать только UNC-пути (например, \\server\folder\file.xml).Проанализируем программный код выгрузки. Нам необходимо собрать данные запросом, сформировать XML-структуру с помощью объекта ЗаписьXML и передать результат по протоколу FTP. Рассмотрим пример реализации такой процедуры, адаптированной для работы на сервере:
Процедура ВыгрузкаXMLНаСервере() Экспорт
// 1. Подготовка пути к файлу
// Используем UNC-путь, так как локальные диски сервера могут быть недоступны
ИмяФайла = "\\clsdtc2\files\VigrS1C\OH.xml";
ЗаписьXML = Новый ЗаписьXML;
Попытка
ЗаписьXML.ОткрытьФайл(ИмяФайла);
Исключение
ЗаписьЖурналаРегистрации("ВыгрузкаXML", УровеньЖурналаРегистрации.Ошибка, , ,
"Не удалось открыть файл для записи: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("Выгрузка1С");
// 2. Формирование запроса к данным
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВводВторичныхОбъектовВторичныеОбъекты.Объект КАК Объект,
| ВводВторичныхОбъектовВторичныеОбъекты.Объект.Наименование КАК Номер,
| ВводВторичныхОбъектовВторичныеОбъекты.ПриведеннаяПлощадь КАК Площадь,
| СтатусыВторичныхОбъектовСрезПоследних.Статус КАК Статус
|ИЗ
| Документ.ВводВторичныхОбъектов.ВторичныеОбъекты КАК ВводВторичныхОбъектовВторичныеОбъекты
|ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СтатусыВторичныхОбъектов.СрезПоследних КАК СтатусыВторичныхОбъектовСрезПоследних
| ПО ВводВторичныхОбъектовВторичныеОбъекты.Объект = СтатусыВторичныхОбъектовСрезПоследних.Объект";
Выгрузка = Запрос.Выполнить().Выгрузить();
Для Каждого Строка ИЗ Выгрузка Цикл
ЗаписьXML.ЗаписатьНачалоЭлемента("ОбъектНедвижимости");
ЗаписьXML.ЗаписатьАтрибут("Номер", Строка(Строка.Номер));
ЗаписьXML.ЗаписатьАтрибут("Площадь", Формат(Строка.Площадь, "ЧЦ=15; ЧДЦ=2; ЧГ=0"));
ЗаписьXML.ЗаписатьАтрибут("Статус", Строка(Строка.Статус));
ЗаписьXML.ЗаписатьКонецЭлемента(); // ОбъектНедвижимости
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента(); // Выгрузка1С
ЗаписьXML.Закрыть();
// 3. Отправка на FTP
ФТПХост = "ftp.mysite.com";
ФТППользователь = "admin";
ФТППароль = "password";
// Рекомендуется использовать пассивный режим для серверных соединений
ПассивныйРежим = Истина;
Попытка
ФТП = Новый FTPСоединение(ФТПХост, , ФТППользователь, ФТППароль, , ПассивныйРежим);
ФТП.Записать(ИмяФайла, "export_data.xml");
Исключение
ЗаписьЖурналаРегистрации("ВыгрузкаXML", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка FTP: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Для того чтобы регламентное задание могло вызвать нашу процедуру, выполним следующие шаги:
РегламентныеЗаданияСервер).Экспорт в заголовке процедуры.Переходим к объекту метаданных «Регламентные задания» в дереве конфигурации:
ВыгрузкаДанныхВXML).Проанализируем часто встречающиеся архитектурные ошибки. Часто в исходном коде обработок можно встретить выполнение запросов внутри цикла (например, получение цены для каждого объекта отдельно). Это критически замедляет работу фонового задания при больших объемах данных. Рекомендуется соединять таблицы (цены, остатки, статусы) в одном основном запросе.
Также обратим внимание на использование COM-объектов (например, VBScript.RegExp для регулярных выражений). Если сервер 1С работает под управлением 64-битной ОС, могут возникнуть сложности с инициализацией 32-битных COM-компонент. Рассмотрим возможность замены регулярных выражений встроенными функциями 1С, такими как СтрНайти(), СтрЗаменить() или СтрРазделить().
Поскольку мы не видим процесс выполнения регламентного задания в консоли, единственный способ понять, что пошло не так — использовать Журнал регистрации. Обернем основной блок кода в конструкцию Попытка ... Исключение. В блоке исключения будем записывать текст ошибки. Это позволит нам оперативно выяснить, возникла ли проблема из-за отсутствия прав на папку или из-за ошибки в логике запроса.
Таким образом, соблюдение серверного контекста, использование UNC-путей и корректная настройка прав доступа для службы 1С гарантируют стабильную работу вашей автоматической выгрузки.