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

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

Работа с файлами Microsoft Excel на стороне сервера 1С — это классическая задача, которая часто оборачивается трудностями. Основная проблема заключается в том, что Excel.Application изначально проектировался как интерактивное приложение для рабочего стола, а не как серверный компонент. Когда код исполняется в контексте службы «Агент сервера 1С:Предприятие», он попадает в так называемую «Сессию 0», где нет графического интерфейса и привычного окружения пользователя.

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

Причина 1: Отсутствие необходимых папок профиля (Desktop)

Это самая распространенная «загадочная» причина. Даже если у пользователя, под которым запущен сервер 1С (например, 1c_service), есть права администратора, Excel требует наличия папки Desktop в профиле системного пользователя для корректной инициализации COM-интерфейса. Если этих папок нет, Excel выдает общую ошибку доступа.

Разберем, что нужно сделать. Нам необходимо вручную создать директории, которые ожидает увидеть система:

  1. Перейдем в каталог C:\Windows\System32\config\systemprofile\ и создадим там папку Desktop.
  2. Если используется 64-битная операционная система (что сейчас является стандартом), перейдем в каталог C:\Windows\SysWOW64\config\systemprofile\ и также создадим там папку Desktop.
  3. Назначим полные права на эти созданные папки для пользователя, от имени которого работает служба сервера 1С (в нашем примере это 1c_service).

После создания этих папок во многих случаях COM-объект Excel.Application начинает работать мгновенно без изменения кода.

Причина 2: Использование штатных средств 1С (лучшая альтернатива)

Выясним причину, почему вообще стоит отказаться от COM-объектов. Использование COMОбъект на сервере — это всегда риск утечки памяти и появления «зависших» процессов EXCEL.EXE. Начиная с версии платформы 8.3.6, компания 1С реализовала нативную поддержку работы с файлами xlsx. Это работает быстрее, стабильнее и не требует установки Microsoft Office на сервер. Для тех, кто ищет готовые инструменты, существует универсальная загрузка из Excel (импорт справочников), которая работает без установленного Office.

Посмотрим на пример кода, который заменяет использование COM-объекта на использование объекта ТабличныйДокумент:


&НаСервере
Процедура ПрочитатьФайлНаСервере(АдресВременногоХранилища)
    
    ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВременногоХранилища);
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
    ДвоичныеДанные.Записать(ИмяВременногоФайла);
    
    ТабДок = Новый ТабличныйДокумент;
    Попытка
        ТабДок.Прочитать(ИмяВременногоФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);
        // Далее работаем с ТабДок как с обычной таблицей 1С
    Исключение
        Сообщить("Ошибка чтения файла: " + ОписаниеОшибки());
    КонецПопытки;
    
    УдалитьФайлы(ИмяВременногоФайла);
    
КонецПроцедуры

Этот метод полностью избавляет нас от зависимости от DCOM. Если же ваша задача сложнее и требует обработки множества листов или разных форматов, можно использовать универсальную загрузку файлов Excel и CSV или расширенный импорт данных из различных форматов, таких как ods, xlsb и csv.

Причина 3: Настройка параметров DCOM

Если специфика задачи требует именно оригинального Excel (например, используются сложные макросы или специфическое форматирование), нам придется настроить компоненты DCOM. Выясним, как это сделать правильно:

  1. Запустим оснастку «Службы компонентов» (команда dcomcnfg).
  2. Перейдем в раздел Настройка DCOM и найдем в списке Microsoft Excel Application.
  3. В свойствах на вкладке Удостоверение (Identity) выберем пункт «Этот пользователь» и укажем данные учетной записи 1c_service. Это заставит Excel запускаться всегда в контексте этой учетной записи.
  4. На вкладке Безопасность (Security) в разделах «Разрешения на запуск и активацию» и «Разрешения на доступ» добавим пользователя 1c_service и предоставим ему полные права.

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

Причина 4: Использование ADODB для чтения данных

Существует еще один способ работы с данными Excel на сервере, который работает быстрее COM-автоматизации и не требует наличия установленного Excel. Это использование провайдера ADODB. Мы можем обращаться к листу Excel как к таблице базы данных.

Рассмотрим пример подключения:


Connection = Новый COMОбъект("ADODB.Connection");
ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ИмяФайла + ";Extended Properties=""Excel 12.0 Xml;HDR=YES"";";
Connection.Open(ConnectionString);

Command = Новый COMОбъект("ADODB.Command");
Command.ActiveConnection = Connection;
Command.CommandText = "SELECT * FROM [Лист1$]";
Recordset = Command.Execute();

Пока НЕ Recordset.EOF Цикл
    // Читаем данные: Recordset.Fields(0).Value
    Recordset.MoveNext();
КонецЦикла;

Connection.Close();

Для работы этого метода на сервере должен быть установлен Microsoft Access Database Engine. Этот способ значительно стабильнее, чем запуск полноценного приложения Excel.

Анализ ситуации с временными файлами

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

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

Борьба с «зомби-процессами»

При работе через COM на сервере крайне важно правильно завершать работу приложения. Если произошла ошибка (как в блоке Исключение у автора), процесс EXCEL.EXE может остаться висеть в памяти. В следующий раз он может блокировать доступ к временному файлу.

Проанализируем правильную структуру завершения работы:


Попытка
    ExcelПриложение = Новый COMОбъект("Excel.Application");
    // Код работы с файлом
Исключение
    Сообщить(ОписаниеОшибки());
КонецПопытки;

Если ExcelПриложение <> Неопределено Тогда
    ExcelПриложение.Quit();
    ExcelПриложение = Неопределено;
КонецЕсли;

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

Подводя итог, можно сказать, что решение автора перенести чтение на клиента — это рабочий, но не всегда удобный вариант. Если требуется именно серверная обработка, наиболее надежным способом будет использование объекта ТабличныйДокумент или экспорт справочников в Excel с фильтрами встроенными средствами. В некоторых случаях оправдано даже использование Python при выгрузке в Excel с формулами, что полностью снимает вопросы настройки прав доступа и DCOM.

← На главную