Как сохранить файл выгрузки в XML, если выгрузка выполняется на сервере 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При автоматизации обмена данными между базами 1С часто возникает задача перенести процесс выгрузки в фоновое задание или выполнить его в серверном модуле. Основная сложность заключается в том, что серверный контекст исполнения кода существенно отличается от клиентского. Разберем подробно, почему файл не сохраняется привычными методами и как правильно реализовать эту задачу.

Понимание контекста выполнения на сервере

Прежде чем переходить к коду, проанализируем ситуацию: когда мы запускаем обработку УниверсальныйОбменДаннымиXML на клиенте, программа имеет доступ к вашим локальным дискам (например, C:\MyDocuments). Однако, как только код передается на выполнение серверу (в фоновое задание или через серверную процедуру), среда окружения меняется.

Выясним основные причины проблем:

  1. Права доступа: Сервер 1С:Предприятие работает под определенной системной учетной записью (часто это USR1CV8). У этой учетной записи обычно нет прав на запись в пользовательские папки или на рабочие столы сотрудников.
  2. Отсутствие дисков: Понятие «диск C:» на сервере — это физический диск самого сервера, а не того компьютера, за которым сидит пользователь.
  3. Интерактивные окна: На сервере невозможно вызвать диалог выбора файла. Любая попытка вызвать ДиалогВыбораФайла приведет к ошибке выполнения.

Способ 1. Программный запуск обработки УниверсальныйОбменДаннымиXML

Если нам необходимо использовать уже готовые правила обмена, мы можем запустить обработку УниверсальныйОбменДаннымиXML программно. Рассмотрим, как это сделать правильно, чтобы файл был успешно сформирован на сервере.

Для начала нам нужно подготовить объект обработки и заполнить его параметры. Важно помнить, что на сервере мы должны явно указать путь, к которому у сервера есть доступ. Посмотрим на пример кода:


// Создаем объект обработки на сервере
ОбработкаОбмена = Обработки.УниверсальныйОбменДаннымиXML.Создать();

// Загружаем правила обмена (например, из макета или константы)
ОбработкаОбмена.ИмяФайлаПравилОбмена = "C:\Exchange\Rules.xml"; // Путь на диске сервера!
ОбработкаОбмена.ЗагрузитьПравилаОбмена();

// Указываем параметры выгрузки
ОбработкаОбмена.РежимОбмена = "Выгрузка";
ОбработкаОбмена.ИмяФайлаОбмена = "\\ServerName\Exchange\DataOut.xml"; // Используем UNC-путь
ОбработкаОбмена.ПострочныйВывод = Истина;

// Выполняем выгрузку
ОбработкаОбмена.ВыполнитьВыгрузку();

Важный нюанс: Вместо прямого пути к файлу на сервере, мы рекомендуем использовать временные файлы. Это самый надежный способ избежать проблем с правами доступа. Проанализируем следующий алгоритм:

  1. Создаем временное имя файла с помощью функции ПолучитьИмяВременногоФайла("xml").
  2. Выполняем выгрузку в этот временный файл.
  3. Читаем полученный файл в объект ДвоичныеДанные.
  4. Помещаем эти данные в ХранилищеЗначений или передаем по сети.

Способ 2. Использование планов обмена (рекомендуемый подход)

Как справедливо отмечено в обсуждении на форуме, использование УниверсальныйОбменДаннымиXML для регулярных регламентных заданий — не самый оптимальный путь. Разберем, почему планы обмена эффективнее для серверных задач.

Планы обмена позволяют фиксировать только измененные данные, что значительно снижает нагрузку на сервер. Проанализируем шаги настройки такого обмена:

При использовании планов обмена в современных конфигурациях, запись файла часто происходит не напрямую на диск, а через механизмы БСП, которые могут сразу отправлять XML в веб-сервис или на FTP-сервер, минуя файловую систему сервера.

Способ 3. Работа через временное хранилище и передачу на клиент

Если ваша задача — запустить выгрузку на сервере по инициативе пользователя и вернуть ему результат, рассмотрим схему с использованием ВременногоХранилища. Это позволяет сформировать файл на сервере, где находятся данные, и «отдать» его пользователю для сохранения на его локальный ПК.

Посмотрим на пример реализации серверной части:


&НаСервере
Функция ВыгрузитьДанныеНаСервере()
    ПутьКФайлу = ПолучитьИмяВременногоФайла("xml");
    
    // ... здесь код выгрузки в ПутьКФайлу ...
    
    ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
    АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанные, ЭтаФорма.УникальныйИдентификатор);
    
    // Удаляем временный файл после прочтения
    УдалитьФайлы(ПутьКФайлу);
    
    Возврат АдресХранилища;
КонецФункции

После этого на стороне клиента мы можем использовать метод ПолучитьФайл, чтобы предложить пользователю сохранить результат на его диск.

Практические советы по настройке прав

Если вы все же решили сохранять файл на диск сервера или в сетевую папку, разберем, как избежать ошибок доступа:

1. Сетевые пути: Всегда используйте UNC-формат пути (\\ИмяСервера\Папка\Файл.xml). Сервер 1С не видит сетевые диски, подключенные в сеансе пользователя (например, диск Z:).

2. Настройка прав: Зайдите в свойства целевой папки на сервере. На вкладке «Безопасность» добавьте пользователя, от имени которого запущена служба 1C:Enterprise 8.3 Server Agent. Дайте ему права «Изменение» и «Запись».

3. Использование FTP: Проанализируем ситуацию, когда базы находятся в разных сетях. В этом случае вместо записи на диск лучше использовать встроенный объект СоединениеFTP. Это полностью снимает вопрос прав доступа к локальным папкам сервера.


Прокси = Новый FTPСоединение("ftp.example.com", 21, "User", "Password");
Прокси.УстановитьТекущийКаталог("/exchange/");
Прокси.Записать(ПутьКВременномуФайлу, "data.xml");

Резюме

Для надежного сохранения XML-выгрузки на сервере мы рекомендуем:

← На главную