Как исправить ошибку создания COM-объекта Excel.Application в 1С:Предприятие

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

При разработке обработок загрузки данных из электронных таблиц в базы 1С программисты часто сталкиваются с исключением:

Ошибка при вызове конструктора (COMОбъект): Excel = Новый COMОбъект("Excel.Application"); по причине: -2147221005(0x800401F3): Недопустимая строка с указанием класса

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

Причины возникновения ошибки 0x800401F3

Код ошибки 0x800401F3 указывает на то, что идентификатор класса (ProgID — «Excel.Application») не зарегистрирован в реестре операционной системы в том окружении, где выполняется программный код. Проанализируем типичные ситуации, приводящие к этому сбою:

  1. Выполнение кода на сервере без установленного офисного пакета. Процедура с директивой &НаСервере выполняется серверным процессом 1С (rphost). Если Microsoft Excel установлен только на клиентских рабочих станциях пользователей, а на физическом сервере его нет, сервер 1С не обнаружит нужных записей в ветке реестра HKEY_CLASSES_ROOT.
  2. Несовпадение разрядности (битности). Сервер 1С часто функционирует в 64-разрядном режиме, тогда как установленный офисный пакет может быть 32-разрядным. 64-битный процесс платформы 1С не может напрямую инициализировать 32-битный COM-сервер без специальной настройки суррогатных процессов.
  3. Ограничения прав учетной записи службы. Служба USR1CV8 или аналогичная учетная запись сервера часто не имеет интерактивного профиля пользователя и прав DCOM на запуск приложений MS Office. Корпорация Microsoft официально не рекомендует серверную автоматизацию приложений пакета Office из системных служб.

Способ 1. Перенос чтения файла на сторону клиента

Самое простое и эффективное решение в случае, когда Excel установлен на клиентских компьютерах пользователей, — перенести создание COM-объекта в клиентский контекст с последующей передачей полученных данных на сервер.

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


&НаКлиенте
Процедура ЗагрузитьФайлНаКлиенте(Команда)
	
	Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
	Диалог.Фильтр = "Файлы Excel (*.xlsx;*.xls)|*.xlsx;*.xls";
	
	Если Не Диалог.Выбрать() Тогда
		Возврат;
	КонецЕсли;
	
	ИмяФайла = Диалог.ПолноеИмяФайла;
	
	// Создание COM-объекта в контексте клиента
	Попытка
		ExcelПриложение = Новый COMОбъект("Excel.Application");
	Исключение
		Сообщить("Не удалось запустить Excel на клиенте: " + ОписаниеОшибки());
		Возврат;
	КонецПопытки;
	
	ExcelПриложение.Visible = Ложь;
	ExcelПриложение.DisplayAlerts = Ложь;
	
	Книга = ExcelПриложение.Workbooks.Open(ИмяФайла);
	Лист = Книга.Sheets(1);
	
	МассивДанных = Новый Массив;
	
	НомерСтроки = 2; // Пропускаем строку заголовков
	Пока ЗначениеЗаполнено(Лист.Cells(НомерСтроки, 1).Value) Цикл
		СтрокаДанных = Новый Структура;
		СтрокаДанных.Вставить("Артикул", СокрЛП(Лист.Cells(НомерСтроки, 1).Text));
		СтрокаДанных.Вставить("Количество", Число(Лист.Cells(НомерСтроки, 2).Value));
		СтрокаДанных.Вставить("Цена", Число(Лист.Cells(НомерСтроки, 3).Value));
		
		МассивДанных.Добавить(СтрокаДанных);
		НомерСтроки = НомерСтроки + 1;
	КонецЦикла;
	
	Книга.Close(Ложь);
	ExcelПриложение.Quit();
	ExcelПриложение = Неопределено;
	
	// Передаем прочитанную коллекцию на сервер
	ЗаполнитьДанныеНаСервере(МассивДанных);
	
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьДанныеНаСервере(МассивДанных)
	
	Для Каждого Строка Из МассивДанных Цикл
		НоваяСтрока = Объект.Товары.Добавить();
		НоваяСтрока.Артикул = Строка.Артикул;
		НоваяСтрока.Количество = Строка.Количество;
		НоваяСтрока.Цена = Строка.Цена;
	КонецЦикла;
	
КонецПроцедуры

Способ 2. Чтение через штатный ТабличныйДокумент (без Excel на сервере)

Рассмотрим более современный способ, который вообще не зависит от наличия MS Office и COM-библиотек. Начиная с платформы 8.3, объект ТабличныйДокумент умеет нативно открывать файлы форматов .xlsx и .xls как на клиенте, так и на сервере под Windows или Linux.

Разберем по шагам, как загрузить файл на сервер через временное хранилище и прочитать его:


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

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

Способ 3. Подключение через провайдер ADODB

Если требуется высокая скорость обработки больших таблиц непосредственно на сервере без установки полного пакета Microsoft Office, разберем чтение через провайдер Microsoft.ACE.OLEDB. В этом случае на сервере устанавливается только бесплатный компонент доступа к данным Microsoft Access Database Engine.

Важно: разрядность установленного OLE DB драйвера должна строго соответствовать разрядности сервера 1С:Предприятие (для 64-битного сервера необходим 64-битный драйвер).


&НаСервере
Процедура ПрочитатьЧерезADODB(ИмяФайла)
	
	Соединение = Новый COMОбъект("ADODB.Connection");
	СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ИмяФайла + ";Extended Properties=""Excel 12.0 XML;HDR=YES;"";";
	
	Попытка
		Соединение.Open(СтрокаПодключения);
	Исключение
		Сообщить("Ошибка подключения к ADODB: " + ОписаниеОшибки());
		Возврат;
	КонецПопытки;
	
	НаборЗаписей = Новый COMОбъект("ADODB.Recordset");
	// Выбираем данные с первого листа книги
	ТекстЗапроса = "SELECT * FROM [Лист1$]";
	НаборЗаписей.Open(ТекстЗапроса, Соединение);
	
	Пока Не НаборЗаписей.EOF Цикл
		НоваяСтрока = Объект.Товары.Добавить();
		НоваяСтрока.Артикул = СокрЛП(Строка(НаборЗаписей.Fields("Артикул").Value));
		НоваяСтрока.Количество = Число(НаборЗаписей.Fields("Количество").Value);
		
		НаборЗаписей.MoveNext();
	КонецЦикла;
	
	НаборЗаписей.Close();
	Соединение.Close();
	
КонецПроцедуры

Способ 4. Прямой разбор архива XLSX через ЧтениеZIPФайла и ЧтениеXML

Файлы формата .xlsx представляют собой сжатый zip-архив, содержащий XML-файлы с разметкой и строками. Платформа 1С содержит встроенные механизмы работы с архивами и XML:

  1. С помощью объекта ЧтениеZIPФайла архив распаковывается во временный каталог на сервере.
  2. Из файла xl/sharedStrings.xml с помощью объекта ЧтениеXML загружается пул уникальных строк документа.
  3. Из файла листа (например, xl/worksheets/sheet1.xml) извлекаются координаты ячеек и индексы строк.

Этот способ полностью платформенный, работает предельно быстро, не требует никаких сторонних библиотек и одинаково надежно выполняется в любых операционных системах.

Что делать, если запуск Excel на сервере обязателен

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

  1. Создание каталогов профиля рабочего стола. Серверный процесс Excel завершается аварийно, если в системе отсутствуют каталоги Desktop. Создадим вручную следующие папки:
    • C:\Windows\System32\config\systemprofile\Desktop
    • C:\Windows\SysWOW64\config\systemprofile\Desktop
    Для обеих папок необходимо предоставить полные права учетной записи, от имени которой запущена служба сервера 1С.
  2. Настройка DCOM. Через утилиту dcomcnfg («Службы компонентов») перейдем к настройке приложения «Microsoft Excel Application». На вкладке «Безопасность» назначим права на локальный запуск и активацию для пользователя сервера 1С, а на вкладке «Удостоверение» установим режим запуска «Указанный пользователь» с указанием действующей интерактивной учетной записи.
  3. Согласование разрядностей. При работе 64-битного сервера 1С и 32-битного Office создадим приложение COM+ (суррогатный процесс dllhost.exe), чтобы обеспечить корректную трансляцию обращений между 32- и 64-битными адресными пространствами.
← На главную