При автоматизации бизнес-процессов в 1С разработчики и администраторы часто сталкиваются со следующей проблемой: при попытке загрузить файл Excel на стороне сервера приложений возникает системная ошибка. Обычно она связана с невозможностью инициализации COM-объекта Excel.Application. Сообщение может выглядеть как «Класс не зарегистрирован», «Недопустимая строка указания класса» или сопровождаться кодом ошибки 0x80040154.
В этой статье мы подробно разберем, почему возникает эта ошибка, проанализируем различные варианты ее решения и рассмотрим альтернативные, более надежные способы чтения файлов Excel, которые вообще не требуют установки Microsoft Office на сервере.
---
Для начала выясним первопричину сбоя. В большинстве случаев код обработки написан с использованием технологии COM (Component Object Model). Разработчики вызывают функцию инициализации приложения Microsoft Excel:
Эксель = Новый COMОбъект("Excel.Application");
Этот вызов завершается аварийно по трем основным причинам:
Excel.Application.USR1CV8). У этого пользователя по умолчанию нет прав на запуск и активацию COM-компонентов Microsoft Office, а также отсутствуют необходимые папки профиля для инициализации временных файлов Excel.Рассмотрим детально четыре эффективных способа решения этой проблемы.
---
Самый правильный архитектурный путь — полностью отказаться от использования COM-соединения с Excel на сервере. Платформа 1С:Предприятие обладает мощным встроенным функционалом для парсинга и чтения табличных документов, который работает кроссплатформенно (в том числе под ОС Linux) и не требует наличия сторонних программ.
Рассмотрим, как прочитать файл Excel с помощью объекта ТабличныйДокумент. Мы можем открыть файл, прочитать его структуру и выгрузить данные в таблицу значений через объект ПостроительОтчета:
// Создаем объект табличного документа
ТД = Новый ТабличныйДокумент;
// Читаем файл с диска сервера.
// Способ чтения "Текст" позволяет быстро загрузить данные без потери производительности
ТД.Прочитать(Объект.ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Текст);
// Используем ПостроительОтчета для быстрой конвертации табличного документа в Таблицу Значений
Построитель = Новый ПостроительОтчета;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТД.Область(1, 1, ТД.ВысотаТаблицы, ТД.ШиринаТаблицы));
Построитель.Выполнить();
// Получаем готовую Таблицу Значений с данными файла
ТаблицаДанных = Построитель.Результат.Выгрузить();
Этот метод работает чрезвычайно быстро и не зависит от операционной системы и разрядности платформы. Однако он имеет ограничение: если файл Excel содержит много сложных листов с перекрестными формулами, форматированием или картинками, встроенный парсер табличного документа может прочитать данные с некоторыми искажениями.
Если мы работаем на платформе версии 8.3.15 и выше, мы можем пойти еще дальше и прочитать данные напрямую из потока памяти, полностью избегая записи временных файлов на жесткий диск сервера:
// Получаем двоичные данные файла из временного хранилища
ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(АдресФайлаВоВременномХранилище);
// Создаем поток из двоичных данных
Поток = Новый ПотокИзДвоичныхДанных(ДвоичныеДанныеФайла);
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(Поток, СпособЧтенияЗначенийТабличногоДокумента.Значение);
// Закрываем поток после завершения операции
Поток.Закрыть();
---
Если вам необходимо прочитать большие объемы структурированных данных из файлов Excel без установки полноценного офисного пакета, можно использовать Microsoft ADO. Для этого на сервере достаточно иметь бесплатный системный драйвер Microsoft Access Database Engine.
При этом подходе файл Excel рассматривается сервером как полноценная реляционная база данных, где листы книги — это таблицы, а строки — записи. Проанализируем пример кода для чтения данных через ADO:
Connection = Новый COMОбъект("ADODB.Connection");
Recordset = Новый COMОбъект("ADODB.Recordset");
// Формируем строку подключения для провайдера ACE OLEDB
// HDR=YES указывает, что первая строка содержит заголовки колонок
// IMEX=1 переводит драйвер в режим чтения текстовых данных, что предотвращает искажение типов
СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ПутьКФайлу + ";Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1"";";
Попытка
Connection.Open(СтрокаПодключения);
// Выполняем SQL-запрос к Листу1. Обратите внимание на знак "$" в конце имени листа
ТекстЗапроса = "SELECT * FROM [Лист1$]";
Recordset.Open(ТекстЗапроса, Connection, 1, 1);
Пока НЕ Recordset.EOF Цикл
// Получаем значение первой колонки текущей строки
ЗначениеКолонки = Recordset.Fields(0).Value;
// Переходим к следующей записи
Recordset.MoveNext();
КонецЦикла;
Recordset.Close();
Connection.Close();
Исключение
Сообщить("Ошибка чтения файла через ADO: " + ОписаниеОшибки());
КонецПопытки;
Преимущества метода ADO: очень высокая скорость работы, стабильность при обработке файлов объемом более 100 тысяч строк, отсутствие необходимости держать запущенный процесс excel.exe в памяти сервера.
---
Если специфика вашей задачи требует обязательного использования именно COMОбъект("Excel.Application") (например, необходимо выгрузить данные в сложный брендированный шаблон со сводными таблицами и макросами), придется настроить операционную систему сервера.
Разберем по шагам, как подружить сервер 1С и Microsoft Excel в среде Windows:
Если у вас установлен 32-разрядный Excel на 64-разрядном сервере Windows, откройте консоль администрирования компонентов DCOM специальной командой через меню «Пуск -> Выполнить»:
mmc comexp.msc /32
В открывшемся окне перейдите по пути: Службы компонентов -> Компьютеры -> Мой компьютер -> Настройка DCOM. Найдите в списке компонент Microsoft Excel Application. Нажмите правой кнопкой мыши и откройте «Свойства»:
USR1CV8) и предоставьте ему полные права.В неинтерактивной сессии службы Windows, под которой работает сервер 1С, COM-объект Excel при инициализации пытается обратиться к специальным профильным директориям рабочего стола. Если их нет, процесс завершается ошибкой. Вам необходимо вручную создать следующие папки на сервере:
C:\Windows\SysWOW64\config\systemprofile\DesktopC:\Windows\System32\config\systemprofile\DesktopОбязательно зайдите в свойства созданных папок «Desktop», перейдите на вкладку «Безопасность» и предоставьте пользователю USR1CV8 полные права (Чтение, Запись, Изменение).
Использование COM-соединения на сервере несет колоссальные риски «зависания» фоновых процессов excel.exe в диспетчере задач сервера. Каждая ошибка в коде может приводить к тому, что открытый файл Excel останется заблокированным в ОЗУ, постепенно исчерпывая ресурсы сервера.
Чтобы гарантировать стабильность работы, всегда используйте защищенный блок Попытка...Исключение с явным закрытием приложения в блоке обработки ошибок:
Эксель = Неопределено;
Попытка
Эксель = Новый COMОбъект("Excel.Application");
Эксель.DisplayAlerts = Ложь;
Эксель.Visible = Ложь;
Книга = Эксель.Workbooks.Open(ПутьКФайлу);
// Производим чтение/запись данных
// ...
Книга.Close(Ложь);
Эксель.Quit();
Эксель = Неопределено;
Исключение
// Если произошел сбой, обязательно принудительно закрываем Excel
Если Эксель <> Неопределено Тогда
Попытка
Эксель.Quit();
Исключение
// Подавляем вложенные ошибки
КонецПопытки;
Эксель = Неопределено;
КонецЕсли;
ВызватьИсключение "Ошибка при работе с Excel: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
---
Если на сервере приложений 1С категорически запрещено устанавливать стороннее ПО и производить тонкие системные настройки DCOM, можно перенести всю процедуру чтения файла на сторону клиентского компьютера пользователя (где Excel гарантированно установлен).
Однако помните о ключевом ограничении: это решение не подходит для пользователей веб-клиента, работающих с 1С через интернет-браузеры (Chrome, Safari, Firefox). Политики безопасности современных браузеров полностью блокируют инициализацию любых COM-объектов (ActiveX) на стороне клиента.
Если пользователи работают через «Тонкий клиент» 1С, мы можем реализовать следующую схему работы:
Пример структуры кода для загрузки на клиенте:
&НаКлиенте
Процедура ЗагрузитьФайлНаКлиенте()
#Если МобильныйКлиент Или ВебКлиент Тогда
Предупреждение("Загрузка через COM не поддерживается в веб-клиенте!");
Возврат;
#КонецЕсли
Попытка
Эксель = Новый COMОбъект("Excel.Application");
Исключение
Предупреждение("На вашем компьютере не установлен Microsoft Excel!");
Возврат;
КонецПопытки;
// Производим локальное чтение файла в массив структур
ДанныеДляСервера = ЧитатьЛокальныйФайл(Эксель, Объект.ПутьКФайлу);
// Передаем очищенные данные на сервер
ОбработатьДанныеНаСервере(ДанныеДляСервера);
КонецПроцедуры
---
Подводя итоги нашего детального разбора, мы можем сформулировать следующие правила работы с Excel в среде 1С:
Попытка...Исключение.