При переходе на новые версии Microsoft Office, в частности Excel 2016, разработчики 1С часто сталкиваются с тем, что проверенный годами код для работы через COMОбъект("Excel.Application") перестает функционировать. Самая распространенная проблема — ошибка при вызове метода контекста Open. Система выдает неинформативное сообщение, хотя файл существует, права доступа в порядке, а на старых версиях Excel (2003, 2007) всё работает идеально. Разберем детально, почему это происходит и как настроить систему для стабильной работы.
Рассмотрим стандартный фрагмент кода, который обычно вызывает затруднения в среде Excel 2016:
Excel = Новый COMОбъект("Excel.Application");
Если НЕ ПустаяСтрока(ИмяФайла) Тогда
Попытка
Книга = Excel.WorkBooks.Open(ИмяФайла);
// Дальнейшие манипуляции с книгой
Исключение
Excel.Quit();
Сообщить(ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Проблема заключается в том, что начиная с версии 2010 и выше, Microsoft значительно ужесточила требования к безопасности и окружению, в котором запускается экземпляр Excel. Особенно это критично, если код выполняется на стороне сервера 1С под технической учетной записью.
Это самая неочевидная, но наиболее частая причина отказа метода Open. Для инициализации графического движка (даже в невидимом режиме) Excel требует наличия папки Desktop в профиле пользователя, от имени которого запущен сервер 1С. На серверных ОС (Windows Server 2012/2016/2019) эти папки отсутствуют по умолчанию для системных профилей.
Нам необходимо вручную создать следующие директории:
C:\Windows\SysWOW64\config\systemprofile\DesktopC:\Windows\System32\config\systemprofile\DesktopВажно: После создания папок убедитесь, что у пользователя, под которым работает служба "Агент сервера 1С:Предприятие", есть полные права на чтение и запись в эти директории. Это «оживляет» COM-интерфейс во многих случаях.
Excel 2016 блокирует файлы, полученные из интернета или по почте. Если файл скачан программно, Excel открывает его в режиме "Защищенного просмотра", который блокирует программный доступ через COM. Чтобы решить эту проблему, проделаем следующие действия:
Open.Если файл сформирован сторонней системой (например, выгрузка из другой учетной системы в формате XLS), Excel 2016 может посчитать его поврежденным. Мы можем принудительно указать Excel игнорировать ошибки структуры файла, используя параметр CorruptLoad. Посмотрим, как изменить код 1С:
// Определим константу восстановления
// xlNormalLoad = 0, xlRepairFile = 1, xlExtractData = 2
ПараметрВосстановления = 1;
Попытка
// Метод Open принимает множество параметров. CorruptLoad стоит на 15-й позиции.
Книга = Excel.WorkBooks.Open(ИмяФайла, , , , , , , , , , , , , , ПараметрВосстановления);
Исключение
// Обработка ошибки
КонецПопытки;
Проанализируем этот подход: передача единицы в 15-м параметре заставляет Excel открывать книгу в режиме восстановления (Repair Mode), что часто помогает с файлами Excel 2003, имеющими внутренние несоответствия формату.
Если 1С запускается как фоновое задание, необходимо правильно настроить права доступа в Службах компонентов (DCOM). Рассмотрим шаги настройки:
Win+R, введем comexp.msc /32 (для 32-битного Office) или просто dcomcnfg.Excel 2016 проверяет, совпадает ли расширение файла (например, .xls) с его реальным содержимым. Если внутри файла XML-структура, а расширение .xls — метод Open выдаст ошибку. Чтобы это отключить, воспользуемся изменением системного реестра:
Перейдем в ветку HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Excel\Security и создадим параметр DWORD с именем ExtensionHardening и значением 0.
С учетом всех вышеперечисленных факторов, наиболее устойчивый код для работы с современным Excel будет выглядеть следующим образом:
Excel = Новый COMОбъект("Excel.Application");
Excel.Visible = Ложь;
Excel.DisplayAlerts = Ложь; // Отключаем все диалоговые окна
Попытка
// Пробуем открыть файл с параметром восстановления
Книга = Excel.WorkBooks.Open(ИмяФайла, 0, Истина, , , , Истина, , , , , , , , 1);
// Если нужно пересохранить в современный формат XLSX
// Код формата 51 соответствует XLSX
НовоеИмя = КаталогВременныхФайлов() + "Converted_" + Формат(ТекущаяДата(), "ДФ=yyyyMMddHHmmss") + ".xlsx";
Книга.SaveAs(НовоеИмя, 51);
// Работаем с новой книгой...
Исключение
Сообщить("Не удалось открыть файл: " + ОписаниеОшибки());
КонецПопытки;
Excel.Quit();
Excel = Неопределено;
Важное примечание: Если ваша задача состоит только в чтении данных из файла и вам не нужно сложное форматирование макросов Excel, рассмотрите возможность использования встроенного объекта ТабличныйДокумент. Метод ТабличныйДокумент.Прочитать(ИмяФайла) работает значительно быстрее, не требует наличия установленного Microsoft Office на сервере и полностью избавлен от проблем с DCOM и системными папками.