Почему не сохраняется файл Excel через SaveAs в фоновом задании на сервере 1С?

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

При переносе клиентского кода формирования отчетов в Excel в регламентные или фоновые задания разработчики 1С часто сталкиваются с ситуацией: подключение через COM-объект Excel.Application проходит успешно, листы создаются и заполняются данными, однако на этапе вызова метода SaveAs процесс падает с ошибкой: «Произошла исключительная ситуация (Microsoft Office Excel): Метод SaveAs из класса Workbook завершен неверно».

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

В чем причина ошибки на стороне сервера

Проанализируем контекст выполнения. На клиентской машине Excel запускается в активном пользовательском сеансе, где операционная система автоматически предоставляет все необходимые компоненты рабочего стола и пользовательского окружения. В фоновом же задании 1С код исполняется на сервере под учетной записью службы «Агент сервера 1С:Предприятия».

Приложение Microsoft Excel исторически проектировалось как настольная клиентская программа. При выполнении операции сохранения рабочей книги через COM-интерфейс Excel проверяет наличие специальной служебной папки Desktop (Рабочий стол) в профиле того пользователя, от имени которого запущен процесс. Если эта папка отсутствует, вызов Workbook.SaveAs аварийно прерывается системной ошибкой.

Решение 1. Создание папки Desktop для профиля службы сервера

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

  1. Служба запущена под системной учетной записью (Local System):

    В этом случае необходимо вручную создать папки Desktop в системных профилях Windows на сервере 1С (в зависимости от разрядности установленной ОС и Microsoft Office):

    Для 64-разрядной ОС: C:\Windows\SysWOW64\config\systemprofile\Desktop

    Для 32-разрядной ОС или 64-битного Office: C:\Windows\System32\config\systemprofile\Desktop

    Рекомендуется создать обе эти папки, чтобы исключить влияние разрядности процессов.

  2. Служба запущена под выделенным пользователем (например, USR1CV8):

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

    C:\Users\USR1CV8\Desktop

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

Посмотрим на пример кода, позволяющего программно проверить и создать системные каталоги непосредственно перед началом работы с COM-объектом:


Попытка
    СоздатьКаталог("C:\Windows\SysWOW64\config\systemprofile\Desktop");
Исключение
    // Ошибку игнорируем, если каталог уже существует или нет прав
КонецПопытки;

Попытка
    СоздатьКаталог("C:\Windows\System32\config\systemprofile\Desktop");
Исключение
    // Ошибку игнорируем
КонецПопытки;

Решение 2. Корректная программная работа с COM-объектом Excel

Создание каталога Desktop устраняет падение метода SaveAs, однако для стабильной работы фонового задания необходимо учесть критические нюансы автоматизации Office:

  1. Отключение диалоговых окон: фоновое задание не имеет интерфейса. Если Excel решит вывести вопрос о перезаписи файла или смене формата, задание зависнет навсегда. Обязательно выставляйте свойство DisplayAlerts = Ложь.
  2. Явное указание формата файла: при сохранении в формате XLSX рекомендуется передавать код формата 51 (xlOpenXMLWorkbook).
  3. Освобождение памяти и процессов: сборщик мусора 1С не гарантирует моментальное закрытие COM-процессов. Всегда вызывайте методы закрытия книги и завершения работы Excel в блоке Исключение или Попытка ... ЗавершитьПопытку, чтобы избежать накопления зависших процессов EXCEL.EXE в диспетчере задач сервера.

Рассмотрим правильный шаблон формирования и сохранения файла:


Попытка
    Excel = Новый COMОбъект("Excel.Application");
Исключение
    ЗаписьЖурналаРегистрации("ВыгрузкаExcel", УровеньЖурналаРегистрации.Ошибка,,,
        "Не удалось инициализировать Excel.Application: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

Excel.DisplayAlerts = Ложь;
Excel.Visible = Ложь;

Попытка
    Книга = Excel.Workbooks.Add();
    Лист = Книга.Worksheets(1);
    
    // Заполнение ячеек данными
    Лист.Cells(1, 1).Value = "Тестовые данные";
    
    ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
    
    // Код 51 соответствует формату xlOpenXMLWorkbook (.xlsx)
    Книга.SaveAs(ИмяФайла, 51);
    Книга.Close(Ложь);
Исключение
    ЗаписьЖурналаРегистрации("ВыгрузкаExcel", УровеньЖурналаРегистрации.Ошибка,,,
        "Ошибка при формировании файла: " + ОписаниеОшибки());
    Если Книга <> Неопределено Тогда
        Книга.Close(Ложь);
    КонецЕсли;
КонецПопытки;

Excel.Quit();
Excel = Неопределено;

Решение 3. Альтернативный отказ от COM-объекта (ТабличныйДокумент)

Разработчики Microsoft официально не рекомендуют использовать COM-автоматизацию пакета Microsoft Office на стороне сервера из-за проблем с масштабируемостью и утечками памяти. В платформе 1С:Предприятие существует полностью штатный и безопасный способ сохранения данных в XLSX без использования установленного на сервере MS Excel.

Разберем по шагам, как решить эту задачу стандартными средствами платформы:


ТабДок = Новый ТабличныйДокумент;

// Формируем и заполняем табличный документ стандартными методами платформы
// ...

ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);

Преимущества данного подхода очевидны: код не зависит от разрядности операционной системы, не требует установки пакета Office на сервере, работает на серверах под управлением Linux и гарантированно изолирован от ошибок неинтерактивных сеансов Windows.

← На главную