Как исправить ошибку выполнения файловой операции при выгрузке XML-файла в клиент-серверном режиме 1С?

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

При выгрузке документов или справочников из 1С в файл XML разработчики часто сталкиваются с ситуацией, когда на локальной файловой базе код работает корректно, а в клиент-серверном режиме платформы вылетает ошибка вида: «Ошибка при вызове метода контекста (ОткрытьФайл)... Ошибка при выполнении файловой операции».

Проанализируем причины возникновения этой проблемы и разберем проверенные способы ее решения.

Почему возникает ошибка при выгрузке файла на сервере

Рассмотрим типовой сценарий, в котором проявляется ошибка. На стороне клиента открывается интерактивный диалог выбора файла (объект ДиалогВыбораФайла). Пользователь выбирает путь на своем локальном компьютере или в сетевой папке (например, C:\Users\User\Desktop\File.xml или \\Server\Share\File.xml). Затем выбранный путь передается в серверную процедуру с директивой &НаСервере, где выполняется метод ЗаписьXML.ОткрытьФайл().

В этот момент происходят следующие критические сбои:

  1. Разделение контекстов исполнения. Серверный код выполняется на стороне сервера 1С, а не на компьютере пользователя. Сервер физически не имеет доступа к локальному диску C: клиентского компьютера.
  2. Ограничение прав службы сервера 1С. Если передается сетевой путь (UNC-путь вида \\Server\Share\), служба 1C:Enterprise Server (например, пользователь usr1cv8 или системная учетная запись Local System) часто не имеет прав на чтение и запись в эту сетевую папку.

Способ 1. Формирование XML-строки на сервере и сохранение файла на клиенте

Наиболее оптимальный и универсальный способ — разделить формирование данных и файловую операцию. На сервере сформируем структуру XML прямо в оперативной памяти в виде строки, вернем эту строку на клиент и уже на клиентском компьютере запишем её в файл.

Разберем реализацию этого способа на примере:


&НаКлиенте
Процедура ВыгрузитьXML(Команда)

    ДиалогXML = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
    ДиалогXML.ПолноеИмяФайла = "Перемещение_Товаров_" + СокрЛП(Строка(Объект.Номер)) + "_" + Формат(Объект.Дата, "ДФ=yyyyMMdd");
    ДиалогXML.Фильтр = "Файлы XML (*.xml)|*.xml";

    Если ДиалогXML.Выбрать() Тогда
        ИмяФайла = ДиалогXML.ПолноеИмяФайла;
        
        // Получаем содержимое XML с сервера в виде строки
        ТекстXML = ВыгрузитьXMLНаСервере(Объект.Ссылка);
        
        // Записываем файл на стороне клиента
        ТекстовыйФайл = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.UTF8);
        ТекстовыйФайл.Записать(ТекстXML);
        ТекстовыйФайл.Закрыть();
        
        ПоказатьОповещениеПользователя("Успех", , "Файл успешно выгружен!");
    КонецЕсли;

КонецПроцедуры

&НаСервере
Функция ВыгрузитьXMLНаСервере(СсылкаДокумент)

    XML = Новый ЗаписьXML;
    // Настраиваем запись XML в строку в кодировке UTF-8
    XML.УстановитьСтроку("UTF-8");
    XML.ЗаписатьОбъявлениеXML();
    XML.ЗаписатьНачалоЭлемента("ExportedAccDocData");
    XML.ЗаписатьАтрибут("xmlns", "http://www.site.ru/namespace");

    // Заполнение структуры XML данными
    Обр = Обработки.СозданиеФайлаXMLДляПеремещения.Создать();
    Обр.Выгрузить(XML, СсылкаДокумент);

    XML.ЗаписатьКонецЭлемента();

    // Метод Закрыть() возвращает итоговую строку XML
    Возврат XML.Закрыть();

КонецФункции

В данном примере метод XML.УстановитьСтроку() позволяет избежать любых файловых операций на сервере, исключая ошибки доступа.

Способ 2. Использование временного файла сервера и Временного Хранилища

Если файл выгрузки имеет большой объем и формирование его целиком в оперативной памяти нежелательно, следует использовать безопасный временный каталог сервера и механизм работы с временным хранилищем 1С.

Рассмотрим пошагово этот алгоритм:

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

&НаКлиенте
Процедура ВыгрузитьЧерезХранилище(Команда)

    ДиалогXML = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
    ДиалогXML.Фильтр = "Файлы XML (*.xml)|*.xml";

    Если ДиалогXML.Выбрать() Тогда
        АдресХранилища = СформироватьФайлВХранилищеНаСервере(Объект.Ссылка);
        
        // Получаем двоичные данные из хранилища и сохраняем на клиентском диске
        ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресХранилища);
        ДвоичныеДанные.Записать(ДиалогXML.ПолноеИмяФайла);
        
        ОчиститьВременноеХранилище(АдресХранилища);
    КонецЕсли;

КонецПроцедуры

&НаСервере
Функция СформироватьФайлВХранилищеНаСервере(СсылкаДокумент)

    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xml");
    
    XML = Новый ЗаписьXML;
    XML.ОткрытьФайл(ИмяВременногоФайла, "UTF-8");
    XML.ЗаписатьОбъявлениеXML();
    XML.ЗаписатьНачалоЭлемента("Data");
    
    // Формирование структуры XML...
    
    XML.ЗаписатьКонецЭлемента();
    XML.Закрыть();
    
    // Переводим файл в двоичные данные и помещаем в хранилище
    ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременногоФайла);
    АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
    
    // Обязательно удаляем временный файл на сервере
    УдалитьФайлы(ИмяВременногоФайла);
    
    Возврат АдресХранилища;

КонецФункции

Способ 3. Настройка прав доступа службы сервера 1С

Если архитектура решения требует, чтобы файл генерировался непосредственно сервером 1С в определенный общий сетевой ресурс (например, в папку обмена \\ServerName\Exchange\), необходимо выдать соответствующие права службе 1С.

Выполним следующие шаги настройки:

  1. Откроем оснастку Службы (services.msc) на сервере приложений 1С.
  2. Найдем службу Агент сервера 1С:Предприятие 8.3.
  3. Перейдем в свойства службы на вкладку Вход в систему.
  4. Сменим параметр с «С учетной записью доменного/локального системного пользователя» на конкретного доменного пользователя (например, DOMAIN\1c_service).
  5. Назначим данному пользователю права на чтение и запись в целевую сетевую папку на уровне файловой системы и параметров общей папки.
  6. Перезапустим службу 1С:Предприятия.

После этого метод XML.ОткрытьФайл() сможет успешно записывать данные по UNC-путям вида \\ServerName\Exchange\file.xml напрямую из серверного контекста.

← На главную