Как исправить ошибку "Произошла исключительная ситуация (Microsoft Office Excel): Нет доступа к файлу" при работе на сервере 1С?

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

При разработке механизмов загрузки данных из Excel в клиент-серверном варианте работы 1С:Предприятие разработчики часто сталкиваются с ситуацией, когда код, прекрасно работающий в файловой базе или на клиенте, перестает выполняться на сервере. Одной из самых распространенных ошибок является сообщение: "Произошла исключительная ситуация (Microsoft Office Excel): Нет доступа к файлу... Имени файла или пути не существует".

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

Понимание проблемы: Клиент vs Сервер

Прежде чем переходить к правкам кода или настройкам системы, необходимо четко понимать архитектуру взаимодействия.

Если пользователь выбирает файл на своем рабочем столе (например, C:\Users\User\Desktop\Data.xlsx), этот путь является локальным для компьютера клиента. Когда мы передаем эту строку (путь) на сервер, сервер пытается найти этот файл у себя по тому же пути. Естественно, на сервере в папке C:\Users\User\Desktop\ этого файла нет. Это первая причина ошибки.

Вторая причина, более специфичная для сообщения "Нет доступа", возникает, когда файл физически доступен серверу (например, лежит в сетевой папке), но служба сервера 1С (rphost), работающая от имени системной учетной записи (например, USR1CV8 или Local System), не имеет прав на взаимодействие с Excel или доступа к папке профиля для временных файлов.

Решение 1: Использование метода "ТабличныйДокумент" (Рекомендуемое)

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

Преимущества этого метода:

  1. Не требуется установка Microsoft Office на сервере.
  2. Работает быстрее, так как не запускает тяжелый процесс Excel.
  3. Избавляет от проблем с "зависшими" процессами и правами DCOM.

Рассмотрим код, который позволяет прочитать файл без использования COM:


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

    // Подготовка таблицы для данных
    ТЗ = Новый ТаблицаЗначений;
    ТЗ.Колонки.Добавить("ТочкаВремени");
    ТЗ.Колонки.Добавить("Сотрудник");
    
    // Перебор строк табличного документа
    // Начинаем со 2-й строки, если в первой заголовки
    Для Сч = 2 По ТабДок.ВысотаТаблицы Цикл
        
        НоваяСтрока = ТЗ.Добавить();
        // Получаем область ячейки и берем её текст
        НоваяСтрока.ТочкаВремени = ТабДок.ПолучитьОбласть(Сч, 1, Сч, 1).ТекущаяОбласть.Текст;
        НоваяСтрока.Сотрудник    = ТабДок.ПолучитьОбласть(Сч, 2, Сч, 2).ТекущаяОбласть.Текст;
        
    КонецЦикла;

    // Далее обрабатываем ТЗ...

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

Обратите внимание: метод ТабДок.Прочитать требует путь к файлу, который доступен серверу. О том, как доставить файл на сервер, мы поговорим ниже.

Решение 2: Настройка COM-объекта Excel на сервере

Если вам необходимо использовать именно COM-объект (например, для сохранения сложного форматирования или выполнения макросов), и вы получаете ошибку доступа, проблема часто кроется в отсутствии профиля рабочего стола для системного пользователя.

При запуске Excel в неинтерактивном режиме (под службой) он пытается обратиться к системным папкам. Если их нет, возникает исключение.

Что нужно сделать:

  1. Убедитесь, что на сервере установлен Microsoft Excel.
  2. Создайте специальные папки вручную.

Для 64-разрядной (x64) системы создайте папку:

C:\Windows\System32\config\systemprofile\Desktop

Для 32-разрядной (x86) системы (или если установлен 32-битный Office на x64 системе) создайте папку:

C:\Windows\SysWOW64\config\systemprofile\Desktop

Важно: Даже если вы используете 64-битную ОС, но Excel 32-битный, необходимо создать папку именно в SysWOW64. Рекомендуется создать обе папки, чтобы гарантировать работоспособность.

После создания папок необходимо проверить права доступа к ним. У пользователя, от имени которого запущена служба сервера 1С, должны быть полные права на эти папки.

Правильная архитектура: Передача файла с Клиента на Сервер

Независимо от выбранного метода чтения (через ТабличныйДокумент или COMОбъект), файл сначала нужно передать с компьютера пользователя на сервер 1С. Просто передать строковый путь вида "C:\" нельзя.

Давайте разберем правильный алгоритм действий:

  1. На клиенте: Пользователь выбирает файл.
  2. На клиенте: Мы помещаем этот файл во временное хранилище (передаем бинарные данные на сервер).
  3. На сервере: Получаем данные из хранилища и сохраняем их во временный файл на диске сервера.
  4. На сервере: Обрабатываем этот временный файл.
  5. На сервере: Удаляем временный файл.

Пример реализации:

1. Код на Клиенте (выбор и передача):


&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
    
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    Диалог.Фильтр = "Файлы Excel (*.xls;*.xlsx)|*.xls;*.xlsx";
    
    Если Диалог.Выбрать() Тогда
        
        // Помещаем файл во временное хранилище
        // УникальныйИдентификатор формы позволяет привязать файл к жизни формы
        АдресВХранилище = "";
        ПоместитьФайл(АдресВХранилище, Диалог.ПолноеИмяФайла, , Ложь, УникальныйИдентификатор);
        
        // Вызываем серверную процедуру
        ОбработатьФайлНаСервере(АдресВХранилище, Диалог.ПолноеИмяФайла);
        
    КонецЕсли;

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

2. Код на Сервере (получение и чтение):


&НаСервере
Процедура ОбработатьФайлНаСервере(АдресВХранилище, ИсходноеИмяФайла)
    
    // Получаем расширение файла, чтобы сохранить его правильно
    Расширение = Прав(ИсходноеИмяФайла, 4); 
    Если Найти(Расширение, ".") = 0 Тогда
        Расширение = ".xlsx"; // Значение по умолчанию
    КонецЕсли;

    // Получаем имя временного файла на сервере
    ПутьНаСервере = ПолучитьИмяВременногоФайла(Расширение);
    
    // Получаем двоичные данные из хранилища
    ДанныеФайла = ПолучитьИзВременногоХранилища(АдресВХранилище);
    
    // Записываем файл на диск сервера
    ДанныеФайла.Записать(ПутьНаСервере);
    
    // Теперь по пути ПутьНаСервере файл физически существует на сервере
    // Можно использовать ТабДок.Прочитать(ПутьНаСервере)
    // Или Excel.Workbooks.Open(ПутьНаСервере)
    
    Попытка
        ОбработатьДанные(ПутьНаСервере); // Ваша процедура разбора
    Исключение
        Сообщить(ОписаниеОшибки());
    КонецПопытки;
    
    // Обязательно удаляем временный файл после использования
    УдалитьФайлы(ПутьНаСервере);

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

Дополнительные рекомендации

Если вы все же используете COMОбъект("Excel.Application"), помните о необходимости освобождать ресурсы. Процессы Excel могут оставаться в памяти сервера, если их не закрыть принудительно, что со временем приведет к нехватке оперативной памяти.

Всегда оборачивайте работу с COM в конструкцию Попытка ... Исключение и в блоке исключения (или после успешного выполнения) вызывайте методы закрытия:


Попытка
    Excel = Новый COMОбъект("Excel.Application");
    Книга = Excel.Workbooks.Open(ПутьКФайлу);
    // ... чтение данных ...
    Книга.Close(0); // Закрываем книгу без сохранения
Исключение
    // Логирование ошибки
КонецПопытки;

// Завершаем процесс Excel
Если Excel <> Неопределено Тогда
    Excel.Quit();
    Excel = Неопределено;
КонецЕсли;

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

← На главную