При работе в среде терминального сервера (RDP) программисты и системные администраторы часто сталкиваются со специфической и труднодиагностируемой ошибкой при попытке программно подключиться к Excel из 1С. На строчке кода, где инициализируется новый COM-объект, система внезапно выдает сообщение: -2147418113(0x8000FFFF): Разрушительный сбой.
Особенность этой ошибки заключается в ее бессистемности. В один день у пользователя все работает отлично, а на следующий день загрузка данных ломается еще до момента выбора самого файла. При этом у других пользователей в той же базе все может функционировать без сбоев. Выясним причину этой неполадки, разберем сопутствующие системные факторы и рассмотрим альтернативные варианты решения проблемы, включая полный уход от использования COM-технологий.
Код ошибки 0x8000FFFF (в десятичном представлении -2147418113) переводится в системе Windows как Catastrophic failure (Разрушительный сбой). Это общая внутренняя системная ошибка COM-подсистемы (Component Object Model). Она сигнализирует о том, что клиентское приложение (в нашем случае 1С) отправило запрос к внешнему COM-серверу (в нашем случае Excel), но среда выполнения COM не смогла корректно инициализировать объект или потеряла с ним связь в процессе создания.
Рассмотрим подробнее основные технические причины, которые приводят к такому сбою на терминальном сервере:
excel.exe. При новой попытке создания COM-объекта система пытается подключиться к уже запущенному, но зависшему процессу в этой же сессии, что и вызывает разрушительный сбой.USR1CV82 или SYSTEM), у нее могут отсутствовать стандартные пути окружения Windows, такие как папка Desktop.Использование COM-соединения для чтения файлов Excel — это устаревший подход, который тянется со времен платформы 1С 7.7. Начиная с версии платформы 8.3, у разработчиков появился современный, быстрый и кроссплатформенный инструмент для работы с электронными таблицами, не требующий установки Microsoft Excel на сервере или клиентских компьютерах.
Проанализируем ситуацию: если вашей задачей является только чтение данных из готового файла Excel и последующая обработка строк, вам вообще не нужен COM-объект. Мы можем загрузить файл напрямую в объект платформы ТабличныйДокумент.
Разберем по шагам, как переписать код загрузки данных:
// Создаем объект ТабличныйДокумент для чтения данных
ТабДок = Новый ТабличныйДокумент;
Попытка
// Читаем файл Excel напрямую средствами платформы 1С
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Исключение
ВызватьИсключение "Не удалось прочитать файл Excel! Ошибка: " + ОписаниеОшибки();
КонецПопытки;
// Теперь мы можем работать с табличным документом как с обычной таблицей 1С
КоличествоСтрок = ТабДок.ВысотаТаблицы;
КоличествоКолонок = ТабДок.ШиринаТаблицы;
Для НомерСтроки = 1 По КоличествоСтрок Цикл
// Читаем данные из ячеек (например, артикул и количество)
Артикул = ТабДок.ПолучитьОбласть("R" + НомерСтроки + "C1").ТекущийОбъект.Текст;
Количество = ТабДок.ПолучитьОбласть("R" + НомерСтроки + "C2").ТекущийОбъект.Текст;
// Обрабатываем полученные данные
Если ЗначениеЗаполнено(Артикул) Тогда
// Здесь пишем логику добавления данных в документ (например, в Заказ поставщику)
КонецЕсли;
КонецЦикла;
Преимущества данного метода:
Прочитать() происходит в несколько раз быстрее, чем последовательное обращение к ячейкам через COM-соединение.Если специфика вашей задачи все же требует обязательного использования COM-объекта (например, вы используете сложные макросы, VBA-скрипты внутри книги или специфическое форматирование Excel при выгрузке), необходимо устранить конфликт разрядностей программного обеспечения.
Посмотрим на конфигурацию ПО. Если у вас используется 64-битная платформа 1С и 32-битный MS Excel, система будет регулярно выдавать сбои. Для решения этой проблемы выполните одно из следующих действий:
В случае работы на терминальном сервере необходимо регулярно контролировать запущенные сеансы. Если у конкретного пользователя возник «Разрушительный сбой», попробуем завершить все его зависшие сессии Excel.
Выполните следующие действия на сервере:
excel.exe, принадлежащие проблемному пользователю, и завершите их вручную.taskkill /f /fi "username eq ИМЯ_ПОЛЬЗОВАТЕЛЯ" /im excel.exe
В коде 1С обязательно проверяйте, чтобы в блоке закрытия и при возникновении исключений всегда присутствовало явное освобождение памяти от COM-объектов:
Попытка
Excel = Новый COMОбъект("Excel.Application");
// Код работы с файлом
// ...
Excel.Quit();
Excel = Неопределено;
Исключение
// В случае ошибки обязательно закрываем процесс Excel
Если Excel <> Неопределено Тогда
Excel.Quit();
Excel = Неопределено;
КонецЕсли;
ЗаписатьЛогОшибки(ОписаниеОшибки());
КонецПопытки;
Если ошибка возникает из-за некорректных прав доступа в терминальной среде, нам потребуется отрегулировать параметры запуска COM-компонентов Microsoft Excel.
Выполним настройку по шагам:
dcomcnfg и нажмите Enter. Если вы настраиваете 32-битную версию Excel на 64-битной операционной системе Windows, оснастку нужно запускать альтернативной командой:
mmc comexp.msc /32
Иногда ошибка инициализации 0x8000FFFF вызвана отсутствием папок рабочего стола в системном профиле Windows. Это критично, если код 1С запускается в фоне или под системной службой, но также может влиять на терминальных пользователей с поврежденными путями в реестре.
Для исправления этой проблемы:
Desktop в системных профилях Windows по следующим путям:
C:\Windows\System32\config\systemprofile\DesktopC:\Windows\SysWOW64\config\systemprofile\Desktop (для 64-битных ОС)USR1CV82) полные права на чтение и запись для созданных папок Desktop.%TEMP%, а также сбросить настройки интеграции Office в ветке реестра:
HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Excel
(где 14.0 — это версия вашего MS Office, для Excel 2010). При следующем запуске Excel автоматически пересоздаст эти параметры с чистыми значениями по умолчанию.
Мы подробно разобрали причины возникновения ошибки 0x8000FFFF (Разрушительный сбой). Наиболее надежным и архитектурно правильным решением при разработке в среде 1С 8.3 является отказ от использования COM-соединений и переход на чтение файлов Excel с помощью встроенного метода ТабличныйДокумент.Прочитать(). Это избавит вас от необходимости администрирования разрядностей, контроля фоновых процессов и настройки прав DCOM на сервере.