При программной работе с документами Microsoft Excel через механизмы OLE/COM-автоматизации разработчики 1С часто сталкиваются со сбоем на этапе вызова метода Open объекта Workbooks. Внешне ошибка может проявляться внезапно: например, в автономных внешних обработках код отрабатывает штатно, но при вызове из модуля документа или справочника возникает исключение.
Разберем основные причины возникновения этой проблемы, посмотрим на готовые решения и проанализируем альтернативные варианты импорта данных без непосредственного запуска приложения Excel.
Одной из самых частых и неочевидных причин ошибки является некорректная передача параметра пути к файлу. Если путь к документу берется из реквизита формы или диалога (которые могут иметь фиксированную длину), в конце строки часто остаются невидимые символы пробелов.
Проанализируем ситуацию: функция проверки существования файла ФС.СуществуетФайл() может успешным образом отбрасывать концевые пробелы и подтверждать наличие файла на диске. Однако метод COM-объекта Workbooks.Open() получает строку «как есть» и пытается открыть путь с пробелами в конце, что приводит к неудаче и вызову ошибки.
Для гарантированного устранения этой проблемы обязательно применяйте функцию очистки непечатаемых символов СокрЛП() при передаче пути к файлу.
Рассмотрим правильный пример инициализации COM-объекта и открытия файла Excel:
// Создаем OLE-подключение к Excel
Попытка
Эксел = СоздатьОбъект("Excel.Application");
Исключение
Предупреждение("На компьютере не установлен Microsoft Excel!");
Возврат;
КонецПопытки;
// Открываем файл с обязательной обрезкой пробелов в пути
ПутьКФайлу = СокрЛП(ФайлДанных);
Попытка
Книга = Эксел.Workbooks.Open(ПутьКФайлу);
ТекущийЛист = Книга.Worksheets(1);
Исключение
Сообщить("Не удалось открыть файл Excel: " + ОписаниеОшибки());
Эксел.Quit();
Возврат;
КонецПопытки;
Вторая распространенная причина ошибки — нахождение в памяти операционной системы «зависших» процессов EXCEL.EXE от предыдущих некорректных или завершенных с ошибкой сеансов.
Выясним, что происходит при повторном вызове кода: если предыдущий экземпляр Excel не был корректно закрыт методом Quit() и не были очищены COM-переменные, повторное открытие файлов в скрытом режиме блокируется.
Кроме того, если файл сформирован сторонней системой или выгружен из веб-сервиса, при интерактивном открытии Excel может выводить предупреждения (например, о несоответствии формата расширению или о защищенном просмотре Protected View). В скрытом COM-режиме диалоговое окно не отображается, а метод Open останавливает работу по тайм-ауту с ошибкой обращения к свойству.
Правила для предотвращения зависания процессов:
Эксел.Quit() в блоках обработки ошибок или после завершения считывания данных.Эксел.DisplayAlerts = 0.Если OLE-автоматизация работает нестабильно из-за особенностей разрядности операционной системы (например, Windows 64-bit) или версии Microsoft Office, рассмотрим альтернативный подход — чтение Excel-файла как базы данных с помощью ODBC.
Этот способ работает значительно быстрее OLE/COM, не требует запуска сам процесс Excel и не зависает на модальных окнах.
Посмотрим на пример загрузки данных с использованием компоненты ODBCDatabase:
BaseExel = СоздатьОбъект("ODBCDatabase");
СтрокаСоединения = "DRIVER={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};ReadOnly=1;PageTimeout=5;MaxScanRows=8;FIL=excel 12.0;DriverId=1046;DBQ=" + СокрЛП(ПутьКФайлу) + ";";
Если BaseExel.Соединение(СтрокаСоединения) = 0 Тогда
Сообщить(BaseExel.ПолучитьОписаниеОшибки());
Возврат;
КонецЕсли;
Команда = СоздатьОбъект("ODBCRecordSet");
Команда.УстБД(BaseExel);
ТекстЗапроса = "SELECT * FROM [Лист1$]";
Попытка
НаборЗаписей = Команда.ВыполнитьИнструкцию(ТекстЗапроса);
Исключение
Сообщить("Ошибка выполнения запроса: " + ОписаниеОшибки());
BaseExel.Закрыть();
Возврат;
КонецПопытки;
Подводя итоги, при возникновении ошибки «Невозможно получить свойство Open класса Workbooks» первым делом проверьте корректность текстового пути с помощью СокрЛП(), убедитесь в отсутствии висящих процессов EXCEL.EXE в Диспетчере задач и при необходимости рассмотрите переход на прямое чтение файлов через ODBC.