Почему не открывается файл Excel через COM-объект на сервере 1С и как это исправить?

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

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

Причина 1. Настройка прав DCOM и учетной записи службы 1С

Проанализируем контекст выполнения кода: регламентные задания всегда выполняются на стороне сервера под учетной записью, от имени которой запущена служба 1C:Enterprise Server Agent (обычно это системная учетная запись USR1CV8 или SYSTEM). По умолчанию у этой учетной записи нет достаточных прав на запуск и активацию COM-компонентов Microsoft Excel.

Для исправления прав выполним следующие действия:

  1. Откроем оснастку управления службами компонентов: нажмем сочетание клавиш Win + R, введем команду dcomcnfg и нажмем Enter. Если сервер 1С 64-битный, а пакет MS Office установлен 32-битный, консоль необходимо запускать командой mmc comexp.msc /32.
  2. Перейдем по дереву: Службы компонентов -> Компьютеры -> Мой компьютер -> Настройка DCOM.
  3. Найдем в списке приложение Microsoft Excel Application, откроем его свойства и перейдем на вкладку Безопасность.
  4. В разделах Права на запуск и активацию и Права доступа переключим переключатели в положение Настроить, нажмем Изменить и добавим пользователя, под которым работает служба сервера 1С (например, USR1CV8), предоставив ему полные права (Локальный запуск, Локальная активация, Локальный доступ).
  5. На вкладке Удостоверение выберем вариант Указанный пользователь (или Интерактивный пользователь, если требуется тестирование) и зададим учетные данные пользователя с правами администратора.
  6. Проверим наличие действующей лицензии MS Office, так как при отсутствии активации офисный пакет блокирует фоновую работу служб.

Причина 2. Отсутствие системных каталогов Desktop

Выясним еще одну скрытую архитектурную особенность MS Excel: при инициализации и открытии рабочих книг серверная служба Excel пытается обратиться к каталогу рабочего стола профиля текущей учетной записи. Если системная служба запущена от системного профиля, а каталог отсутствует, COM-объект падает с неопределенной ошибкой.

Для решения этой проблемы создадим вручную следующие папки на сервере:

  1. Для 32-разрядных систем: C:\Windows\System32\config\systemprofile\Desktop
  2. Для 64-разрядных систем (обязательно обе папки):
    C:\Windows\System32\config\systemprofile\Desktop
    C:\Windows\SysWOW64\config\systemprofile\Desktop
  3. Назначим для созданных каталогов полные права доступа учетной записи службы 1С (USR1CV8).

Корректная работа с COM-объектом Excel в коде 1С

Рассмотрим, как правильно инициализировать и гарантированно освобождать ресурсы при работе с COM-объектом на сервере. Обязательно нужно отключать интерактивные окна и предупреждения, иначе регламентное задание зависнет при попытке Excel показать невидимое диалоговое окно.

Посмотрим на пример безопасного кода:


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

Книга = Неопределено;

Попытка
    Книга = ExcelПриложение.Workbooks.Open(ПутьКФайлу);
    Лист = Книга.Sheets(1);
    
    // Выполняем чтение данных
    // Например: Значение = Лист.Cells(1, 1).Value;
    
Исключение
    ЗаписьЖурналаРегистрации("ЧтениеExcel", УровеньЖурналаРегистрации.Ошибка,,, 
        "Ошибка при чтении файла: " + ОписаниеОшибки());
КонецПопытки;

// Корректное закрытие и освобождение памяти
Если Книга <> Неопределено Тогда
    Книга.Close(Ложь);
КонецЕсли;

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

Альтернативные способы чтения Excel без использования COM

Использование COM-объекта Excel.Application на сервере официально не рекомендуется компанией Microsoft из-за высоких накладных расходов, утечек памяти и нестабильности при параллельных вызовах. Рассмотрим более надежные и быстрые методы загрузки данных, которые не требуют установки MS Office на сервер.

1. Чтение через штатный ТабличныйДокумент 1С

Начиная с версии платформы 8.3.6, объект ТабличныйДокумент умеет напрямую читать файлы форматов .xls, .xlsx и .ods на стороне сервера, в том числе под управлением ОС Linux. Это самый предпочтительный и стабильный способ.


ТабДок = Новый ТабличныйДокумент;
Попытка
    ТабДок.Прочитать(ПутьКФайлу);
Исключение
    ВызватьИсключение "Не удалось прочитать файл: " + ОписаниеОшибки();
КонецПопытки;

ВсегоСтрок = ТабДок.ВысотаТаблицы;
ВсегоКолонок = ТабДок.ШиринаТаблицы;

Для НомерСтроки = 1 По ВсегоСтрок Цикл
    Для НомерКолонки = 1 По ВсегоКолонок Цикл
        ЗначениеЯчейки = ТабДок.Область(НомерСтроки, НомерКолонки).Текст;
        // Обработка полученного значения
    КонецЦикла;
КонецЦикла;

2. Чтение через ADO (Microsoft.ACE.OLEDB)

Если требуется высокая скорость обработки больших массивов данных, разберем чтение файла как реляционной базы данных с помощью технологии ADO. Для этого на сервер достаточно установить бесплатный компонент Microsoft Access Database Engine соответствующей разрядности.


Соединение = Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ПутьКФайлу + ";Extended Properties=""Excel 12.0 XML;HDR=YES;"";";

Попытка
    Соединение.Open(СтрокаПодключения);
    Команда = Новый COMОбъект("ADODB.Command");
    Команда.ActiveConnection = Соединение;
    Команда.CommandText = "SELECT * FROM [Лист1$]";
    
    Выборка = Команда.Execute();
    
    Пока Не Выборка.EOF Цикл
        // Доступ к колонкам: Выборка.Fields.Item(0).Value
        Выборка.MoveNext();
    КонецЦикла;
    
    Выборка.Close();
    Соединение.Close();
Исключение
    Соединение = Неопределено;
    ВызватьИсключение "Ошибка ADO: " + ОписаниеОшибки();
КонецПопытки;

Соединение = Неопределено;

3. Прямой парсинг структуры XLSX как архива

Файл формата .xlsx представляет собой сжатый ZIP-архив с набором XML-файлов. Мы можем распаковать его с помощью объекта ЧтениеZipФайла и прочитать данные таблиц напрямую через ЧтениеXML. Этот подход обеспечивает максимальную кроссплатформенность и полностью исключает любые внешние зависимости от библиотек операционной системы.

← На главную