При попытке открыть книгу Excel через COM-соединение непосредственно в серверном контексте 1С разработчики часто сталкиваются с ошибкой: «Нет доступа к файлу». При этом файл физически присутствует на диске сервера, не заблокирован другими программами, а проверка через Файл.Существует() возвращает положительный результат. Разберем детально, почему серверный процесс не может открыть файл, как правильно настроить операционную систему и DCOM, а также какие более надежные альтернативы чтению через COM существуют в платформе 1С:Предприятие.
Проанализируем механизм запуска Microsoft Excel службой сервера. Служба 1С (обычно под учетной записью usr1cv8 или системной учетной записью) функционирует в неинтерактивной сессии Windows (Session 0). Для инициализации COM-объекта приложению Excel обязательно требуется наличие каталога рабочего стола в системном профиле. Если папка отсутствует, Excel завершает открытие книги с ошибкой прав доступа.
Для исправления создадим необходимые служебные каталоги вручную:
C:\Windows\SysWOW64\config\systemprofile\ и создадим папку Desktop.C:\Windows\System32\config\systemprofile\ и также создадим каталог Desktop.Выясним распространенное заблуждение: установка прав для группы «Все» в свойствах файла или папки не всегда гарантирует доступ службе 1С. Служба сервера 1С:Предприятия запускается от имени специального локального или доменного пользователя (по умолчанию usr1cv8).
Разберем по шагам проверку и назначение прав:
services.msc) и найдем службу «Агент сервера 1С:Предприятия». Проверим, какой пользователь указан на вкладке «Вход в систему»..\usr1cv8) и предоставим ему права на чтение, запись и изменение.Посмотрим на настройки компонента DCOM. По умолчанию приложение Microsoft Excel не настроено для запуска из-под системных сервисов. Настроим параметры безопасности компонента:
dcomcnfg.exe. Если сервер 1С 64-битный, а установленный Microsoft Office 32-битный, откроем 32-разрядную консоль командой: mmc comexp.msc /32.usr1cv8), выдав полные локальные права.Проанализируем, как передан путь к файлу. Служба сервера 1С изолирована от сеансов пользователей. Если путь к файлу указан через букву подключенного сетевого диска (например, Z:\import\file.xlsx), сервер 1С этот диск не увидит, так как монтирование дисков выполняется только внутри интерактивного сеанса конкретного пользователя. Путь должен быть строго локальным (например, D:\Exchange\file.xlsx) либо задаваться в формате UNC (сетевого пути): \\ServerName\ShareName\file.xlsx.
Запуск клиентских офисных приложений через COM-объекты на стороне сервера официально не рекомендуется разработчиками. Фоновые процессы EXCEL.EXE могут «зависать» в памяти при возникновении модальных предупреждений, исчерпывать системный пул памяти и блокировать файлы при некорректном завершении работы.
Рассмотрим гораздо более надежный, производительный и кроссплатформенный вариант, не требующий установки Microsoft Office на сервере и настройки прав DCOM. Платформа 1С:Предприятие умеет напрямую загружать файлы Excel с помощью встроенного объекта ТабличныйДокумент.
Посмотрим на пример кода, выполняемого на стороне сервера:
&НаСервере
Процедура ПрочитатьФайлExcelНаСервере(ПутьКФайлу)
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ПутьКФайлу);
Исключение
ВызватьИсключение "Не удалось прочитать файл: " + ОписаниеОшибки();
КонецПопытки;
// Обходим прочитанные строки и колонки
ВсегоСтрок = ТабДок.ВысотаТаблицы;
ВсегоКолонок = ТабДок.ШиринаТаблицы;
Для НомерСтроки = 1 По ВсегоСтрок Цикл
Для НомерКолонки = 1 По ВсегоКолонок Цикл
ЗначениеЯчейки = ТабДок.Область(НомерСтроки, НомерКолонки).Текст;
// Обработка полученного значения
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Если требуется работать с таблицами больших объемов, разберем чтение файла Excel как реляционной базы данных с помощью провайдера OLE DB. В этом случае экземпляр Excel в памяти не создается, а данные извлекаются через стандартные SQL-запросы:
&НаСервере
Функция ПрочитатьExcelЧерезADODB(ПутьКФайлу, ИмяЛиста)
Соединение = Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ПутьКФайлу + ";Extended Properties=""Excel 12.0 Xml;HDR=YES;"";";
Попытка
Соединение.Open(СтрокаПодключения);
НаборЗаписей = Новый COMОбъект("ADODB.Recordset");
ТекстЗапроса = "SELECT * FROM [" + ИмяЛиста + "$]";
НаборЗаписей.Open(ТекстЗапроса, Соединение);
Пока НЕ НаборЗаписей.EOF Цикл
// Считывание полей: НаборЗаписей.Fields.Item("ИмяКолонки").Value
НаборЗаписей.MoveNext();
КонецЦикла;
НаборЗаписей.Close();
Соединение.Close();
Исключение
Если Соединение.State = 1 Тогда
Соединение.Close();
КонецЕсли;
ВызватьИсключение ОписаниеОшибки();
КонецПопытки;
КонецФункции
Передавать строковый путь с клиента на сервер некорректно, если файл находится на пользовательском компьютере. В архитектуре клиент-сервер файл сначала необходимо поместить во временное хранилище на клиенте, после чего на сервере извлечь двоичные данные, сохранить их во временный файл и передать на обработку:
&НаСервере
Процедура ОбработатьФайлИзХранилища(АдресВоВременномХранилище)
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВоВременномХранилище);
ВременныйФайл = ПолучитьИмяВременногоФайла("xlsx");
ДвоичныеДанные.Записать(ВременныйФайл);
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ВременныйФайл);
// Удаляем временный файл после прочтения
УдалитьФайлы(ВременныйФайл);
КонецПроцедуры