При переходе с обычных форм на управляемые разработчики часто сталкиваются с проблемой: привычный код создания COM-объекта Новый COMОбъект("Excel.Application") перестает работать. Вызов завершается ошибкой вида -2147221005(0x800401F3): Invalid class string или возвращает значение Неопределено. Разберем причинно-следственные связи этой проблемы и проанализируем правильный подход к написанию кода в контексте управляемого приложения.
В обычных приложениях весь код по умолчанию выполнялся на стороне клиентского компьютера, где установлен пакет Microsoft Office. В управляемых формах логика строго разделена на клиентский и серверный контексты:
COMОбъект("Excel.Application") сервер Windows не может найти зарегистрированный класс OLE/COM, из-за чего возникает ошибка Invalid class string.Чтобы избежать ошибок взаимодействия с COM-объектами на сервере, проанализируем правильное распределение ролей между клиентом и сервером. Вся тяжелая бизнес-логика (выборка данных, выборка компоновки, формирование табличного документа) должна выполняться на сервере, а работа с файловой системой пользователя и внешними COM-приложениями — на клиенте.
Рассмотрим пошагово оптимальную схему реализации этой задачи в модуле формы обработки:
&НаСервере.ТабличныйДокумент или массив документов на клиент.&НаКлиенте) вызываем конструктор COMОбъект("Excel.Application") или сохраняем файл штатным методом.Рассмотрим пример правильного кода в модуле формы:
&НаСервере
Функция СформироватьТабличныйДокументНаСервере()
ТабДокумент = Новый ТабличныйДокумент;
// Выполняем формирование отчета или печатной формы
// ...
Возврат ТабДокумент;
КонецФункции
&НаКлиенте
Процедура СформироватьИОткрытьФайл()
// Step 1: Получаем сформированный документ с сервера
ТабДок = СформироватьТабличныйДокументНаСервере();
// Step 2: Работаем с файлом и Excel на стороне клиента
ИмяФайла = ПолучитьИмяВременногоФайла("xls");
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLS);
Попытка
ExcelApp = Новый COMОбъект("Excel.Application");
ExcelApp.DisplayAlerts = False;
Book = ExcelApp.Workbooks.Open(ИмяФайла);
ExcelApp.Visible = Истина;
Исключение
Сообщить("Не удалось запустить MS Excel: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Если цель заключается только в выгрузке данных в формат Excel без необходимости непосредственного управления окном MS Excel через OLE, можно отказаться от вызова COMОбъект. Встроенный объект ТабличныйДокумент позволяет сохранять документы на сервере без установленного Microsoft Office.
Для этого используется метод Записать() с указанием нужного типа файла:
&НаСервере
Процедура СохранитьОтчетНаСервере(ПутьКФайлу)
ТабДок = Новый ТабличныйДокумент;
// Заполнение табличного документа
// Сохранение напрямую в XLSX без использования COM-объекта Excel
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
КонецПроцедуры
Данный подход является кроссплатформенным, работает на серверах под управлением Linux и не требует настройки прав DCOM или установки дополнительных сторонних программ.