При программной работе с таблицами Microsoft Excel через COM-соединение разработчики нередко сталкиваются с ситуацией, когда при выполнении метода WorkBooks.Open() приложение Excel аварийно завершает работу. Вместо стандартного перехвата ошибки конструкцией Попытка ... Исключение операционная система Windows выводит диалоговое окно «Отправлять отчет / не отправлять», порождает зависший пустой процесс EXCEL.EXE, и только после ручного закрытия окон управление возвращается в блок Исключение. Разберем причины такого поведения и способы решения проблемы.
Выясним причину, почему стандартная конструкция Попытка ... Исключение не отрабатывает мгновенно. Блок исключения в 1С перехватывает ошибки COM-вызовов (HRESULT), которые возвращает сервер автоматизации. Однако если в самом процессе EXCEL.EXE происходит критический сбой уровня операционной системы (падение процесса, сбой в памяти c0000005), управление перехватывает служба Windows Error Reporting (WER). Процесс блокируется операционной системой для сбора дампа, что приводит к зависанию сеанса 1С до момента закрытия диалога пользователем.
К наиболее частым причинам такого сбоя при открытии файлов относятся:
Workbook_Open или Auto_Open, которые при фоновом открытии пытаются обратиться к интерфейсным элементам или содержат ошибки.Рассмотрим подробнее, как подготовить объект Excel.Application перед вызовом метода открытия файла, чтобы минимизировать риск падения процесса. Нам необходимо отключить показ диалоговых окон, запретить макросы и передать безопасные параметры в метод Open.
Посмотрим на пример правильной настройки:
Попытка
Эксель = Новый COMОбъект("Excel.Application");
Исключение
ЗаписьЖурналаРегистрации("Открытие Excel", УровеньЖурналаРегистрации.Ошибка,,, "Не удалось инициализировать COM-объект Excel.Application: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
Попытка
// Отключаем вывод системных предупреждений и запросов Excel
Эксель.DisplayAlerts = Ложь;
// Блокируем выполнение любых макросов (3 = msoAutomationSecurityForceDisable)
Эксель.AutomationSecurity = 3;
// Отключаем обновление экрана для ускорения и стабильности
Эксель.ScreenUpdating = Ложь;
// Открываем книгу с безопасными параметрами:
// UpdateLinks = 0 (не обновлять связи), ReadOnly = Истина
Книга = Эксель.WorkBooks.Open(ИмяФайла, 0, Истина);
// Выполняем полезные действия с данными книги...
Книга.Close(Ложь);
Исключение
ЗаписьЖурналаРегистрации("Открытие Excel", УровеньЖурналаРегистрации.Ошибка,,, "Ошибка при обработке файла: " + ОписаниеОшибки());
КонецПопытки;
// Обязательно корректно выгружаем процесс из памяти
Эксель.Quit();
Эксель = Неопределено;
Разберем важные параметры метода Open. Передача второго параметра со значением 0 отключает обновление связей с другими книгами. Третий параметр со значением Истина открывает книгу в режиме «только для чтения», предотвращая конфликты блокировок при одновременном доступе к файлу.
Проанализируем ситуацию, когда файл еще не освобожден операционной системой или занят фоновой службой. Прежде чем передавать файл тяжелому COM-объекту, проверим возможность монопольного доступа к нему штатным функционалом платформы 1С:
ФайлПроверки = Новый Файл(ИмяФайла);
Если Не ФайлПроверки.Существует() Тогда
ВызватьИсключение "Файл не найден: " + ИмяФайла;
КонецЕсли;
Попытка
// Проверяем возможность открыть файл на чтение без участия сторонних программ
ФайлПоток = Новый ФайловыйПоток(ИмяФайла, РежимОткрытияФайла.Открыть, ДоступКФайлу.Чтение);
ФайлПоток.Закрыть();
Исключение
// Файл заблокирован или поврежден на уровне файловой системы
ЗаписьЖурналаРегистрации("Доступ к файлу", УровеньЖурналаРегистрации.Предупреждение,,, "Файл заблокирован другим процессом: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
Такой подход позволяет отсечь ошибки доступа еще до вызова Microsoft Excel, исключая зависание при монопольной блокировке.
Если сбой происходит внутри сторонних библиотек и полностью исключить падение процесса на рабочей станции не удается, отключим показ системного диалога ошибки. В этом случае операционная система мгновенно завершит аварийный процесс EXCEL.EXE, и управление сразу перейдет в блок Исключение кода 1С без ожидания действий пользователя.
Для отключения окна отчетов об ошибках выполним настройку реестра Windows на клиентской или серверной машине:
regedit.HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting (или аналогичную ветку в HKEY_LOCAL_MACHINE для всех пользователей).DontShowUI, установив его значение равным 1.Использование COM-объекта Excel.Application считается наименее надежным и наиболее ресурсоемким способом интеграции. Для стабильной загрузки данных разберем альтернативные технологии, которые полностью изолированы от сбоев офисного пакета.
Платформа 1С:Предприятие умеет открывать файлы форматов .xls и .xlsx напрямую без установленного на компьютере MS Office. Это работает как на клиенте, так и на сервере под управлением Windows или Linux:
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ИмяФайла);
// Обработка строк и колонок ТабличногоДокумента
Исключение
Сообщить("Не удалось прочитать файл: " + ОписаниеОшибки());
КонецПопытки;
Механизм доступа к файлу как к базе данных через OLE DB / ODBC драйверы Microsoft Jet или ACE. Данный подход работает быстрее COM-автоматизации и не запускает графическое приложение Excel, считывая строки книги SQL-запросом.
Поскольку файлы формата .xlsx представляют собой сжатый zip-пакет, мы можем распаковать его объектом ЧтениеZipФайла и быстро прочитать данные листов через ЧтениеXML (файлы sheet1.xml и словарь sharedStrings.xml). Это гарантирует максимальную скорость работы и абсолютную независимость от окружения.