При разработке механизмов интеграции и загрузки данных часто возникает ситуация, когда код, успешно работающий на локальном компьютере или в файловой базе, отказывается работать на сервере 1С. Типичный пример такой проблемы — попытка открыть файл Excel в серверном контексте &НаСервере с помощью COM-объекта Excel.Application.
Процедура аварийно завершается с ошибкой:
«Произошла исключительная ситуация (Microsoft Excel): Метод Open из класса Workbooks завершен неверно».
В этой статье мы подробно проанализируем причины возникновения этой ошибки, разберем по шагам варианты администрирования операционной системы Windows Server для ее устранения, а также рассмотрим современные альтернативные способы чтения файлов Excel, которые позволят полностью отказаться от использования нестабильных COM-объектов на сервере.
Программа Microsoft Excel исторически создавалась как интерактивное настольное приложение. При вызове метода Open Excel пытается инициализировать свой интерфейс, обратиться к настройкам принтера по умолчанию, проверить временные папки пользователя и получить доступ к рабочему столу (папке Desktop).
Когда этот же код выполняется на сервере приложений 1С:
USR1CV8 или SYSTEM).Open.Рассмотрим подробнее три основных способа решения этой проблемы.
---
Самое быстрое административное решение, которое в 80% случаев устраняет ошибку инициализации Excel в фоновом режиме, — это создание недостающих папок рабочего стола в системных каталогах Windows. Без этих папок служба COM-объекта Excel просто не может запуститься.
Выполните следующие шаги на сервере, где установлена служба 1С:Предприятие:
C:\Windows\SysWOW64\config\systemprofile\DesktopC:\Windows\System32\config\systemprofile\DesktopDesktop, откройте «Свойства» -> вкладка «Безопасность» и предоставьте полные права (Full Control) учетной записи, от имени которой запущена служба сервера 1С (например, USR1CV8 или USR1CV83).После создания папок перезапустите службу сервера 1С и проверьте выполнение кода.
---
Если создание папок не помогло, необходимо настроить права доступа к COM-объекту Microsoft Excel напрямую через консоль Служб компонентов Windows. Это позволит серверу 1С беспрепятственно инициализировать процесс excel.exe.
Выполним настройку по шагам:
Win + R, введите команду dcomcnfg и нажмите Enter.
Обратите внимание: Если у вас 64-разрядная Windows и 32-разрядный Excel, стандартная консоль не покажет Excel в списке. В этом случае запустите консоль через команду:
mmc comexp.msc /32
USR1CV83). Выдайте ему все флаги (Локальный запуск, Локальная активация).USR1CV83 с правами на локальный доступ.---
Обратите внимание на то, где именно физически расположен файл. Если в коде прописан путь вроде E:\distr\1.xlsx, а этот диск является локальным диском вашего компьютера (или подключен по RDP как сетевой ресурс), сервер 1С его не увидит. Сервер ищет этот файл на своих собственных локальных дисках.
Чтобы правильно обработать файл, выбранный пользователем на клиенте, его необходимо передать на сервер с помощью временного хранилища. Рассмотрим пример реализации:
&НаКлиенте
Процедура ВыбратьИЗагрузитьФайл(Команда)
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Фильтр = "Файлы Excel (*.xlsx)|*.xlsx";
Если Диалог.Выбрать() Тогда
ИмяФайлаКлиент = Диалог.ПолноеИмяФайла;
// Помещаем файл во временное хранилище на сервере
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ИмяФайлаКлиент);
АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанныеФайла, УникальныйИдентификатор);
// Передаем адрес хранилища на сервер для обработки
ОбработатьФайлНаСервере(АдресХранилища);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ОбработатьФайлНаСервере(АдресХранилища)
// Получаем двоичные данные из хранилища
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресХранилища);
// Создаем временный файл на сервере
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
ДвоичныеДанные.Записать(ИмяВременногоФайла);
// Теперь файл гарантированно лежит на сервере, и мы можем его прочитать
// (Рекомендуется использовать Способ 4 для чтения)
// Не забываем удалить временный файл после работы
Попытка
УдалитьФайлы(ИмяВременногоФайла);
Исключение
// Обработка ошибки удаления
КонецПопытки;
КонецПроцедуры
---
Использование COM-соединения с Excel на стороне сервера несет в себе огромные инфраструктурные риски. Процессы excel.exe имеют свойство «зависать» в памяти сервера приложений, потребляя процессорное время и оперативную память. Кроме того, компания Microsoft официально не рекомендует использовать пакет Office для автоматизации на серверных ОС.
Начиная с версии платформы 8.3.6, в 1С встроен мощный и быстрый механизм прямого чтения файлов XLSX через объект ТабличныйДокумент. Этот способ работает быстрее, стабильнее и вообще не требует установки Microsoft Excel на сервере!
Проанализируем пример кода, который полностью заменяет COM-объект:
&НаСервере
Процедура ПрочитатьExcelБезCOM(ПутьКФайлуНаСервере)
ТабДок = Новый ТабличныйДокумент;
Попытка
// Читаем файл напрямую средствами платформы 1С
ТабДок.Прочитать(ПутьКФайлуНаСервере, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Исключение
ВызватьИсключение "Не удалось прочитать файл Excel. Причина: " + ОписаниеОшибки();
КонецПопытки;
// Определяем границы заполненной области
ВысотаТаблицы = ТабДок.ВысотаТаблицы;
ШиринаТаблицы = ТабДок.ШиринаТаблицы;
// Обходим строки и колонки файла
Для НомерСтроки = 1 По ВысотаТаблицы Цикл
// Пример получения значения из конкретной ячейки
КодТовара = ТабДок.Область(НомерСтроки, 1).Текст;
ИмяТовара = ТабДок.Область(НомерСтроки, 2).Текст;
Цена = ТабДок.Область(НомерСтроки, 3).Значение; // возвращает число, если в ячейке число
Если ЗначениеЗаполнено(КодТовара) Тогда
// Обрабатываем полученные данные
// ...
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Преимущества использования ТабличныйДокумент.Прочитать():
.xlsx платформой происходит быстрее, чем инициализация тяжелого COM-приложения.