Сообщение об ошибке «Компонент ActiveX не может создать объект» отображается для всех объектов

#excel #vba

#excel #vba

Вопрос:

Я не могу создать какие-либо объекты в макросе Excel, который я пытаюсь написать. Первоначально я пытался работать с MSXML2.DOMDocument60, однако я понял, что не могу заставить ActiveX создавать какие-либо объекты. Например, я получаю ту же ошибку (во время выполнения 429 «Компонент ActiveX не может создать объект») для этой строки кода:

 Dim ExcelSheet As Object
Set ExcelSheet = CreateObject("Excel.Sheet")
  

Очевидно, что, поскольку я в Excel, программа установлена правильно, и у нее должен быть доступ к ней. Я проверил несколько других страниц Stackoverflow для этого. Похоже, что это не проблема со ссылкой, и я не могу представить, что приведенный выше простой код не работает из-за отсутствия DLL, поскольку я снова уже в Excel.

Возможно, на моем компьютере есть функция безопасности, блокирующая это действие?

Опять же, моя проблема не в приведенном выше коде. Это был просто простой способ показать, что Create object не работает.

Моя главная цель — заставить работать следующее: Затемнить objXML как MSXML2.DOMDocument60 Установить objXML = CreateObject(«MSXML2.DOMDocument60»)

Я уже проверил, что у меня есть правильная ссылка, и я перерегистрировал библиотеки DLL.

Комментарии:

1. Объекты листа Excel требуют, чтобы вы «прикрепили» к существующему листу, будь то тот, который уже присутствует в рабочей книге, или лист, который вы только что создали. Поэтому используйте что-то вроде Dim thisWS as Worksheet; Set thisWS = ThisWorkbook.Sheets("Sheet1")

2. Привет, Питер. Спасибо за ваш ответ. К сожалению, это не решает мою проблему. Приведенный выше код был предназначен только для примера. Реальная проблема в том, что я, похоже, блокируюсь каждый раз, когда использую «CreateObject», и я не уверен, почему. Я сталкиваюсь с той же проблемой, пытаясь создать объект для документа Word: затемнить oWordApp как Word. Набор приложений oWordApp = CreateObject(«Word. Приложение»)

3. Вы используете Mac?

4. Привет, Тим. Нет. Я на компьютере с Windows 10 с 64-разрядной операционной системой. Версия Excel, которую я использую, — Microsoft 2016, и она 32-разрядная.

5. Почему вы выполняете позднюю привязку ExcelSheet , если вы в Excel? На библиотеку типов уже есть ссылка, вы пробовали посмотреть, что происходит, когда вы это делаете Set ExcelSheet = New Excel.Worksheet ?

Ответ №1:

Я нашел ответ, который искал. В моей компании заблокирован диск C и другой сетевой диск, что не позволяет CreateObject работать при сохранении листа Excel в любом из этих расположений. Вместо этого, сохранив лист Excel на своем рабочем столе, я могу заставить его работать.

Ответ №2:

В объектной модели Excel нет класса с Excel.Sheet ProgID. Вероятно, вы имели в виду Excel.Worksheet , но это тоже не сработает, и это не из CreateObject -за какой-либо неясной функции безопасности.

Проще говоря, не все классы / типы можно создавать: в библиотеке типов Excel Application есть, и это все: все остальное должно быть создано в объектной модели с использованием заводских методов, предоставляемых этим API.

Другими словами, единственный способ, которым вы можете создать Excel.Worksheet , — это если Excel создаст его для вас.

 Set excelSheet = Excel.Application.ActiveWorkbook.Worksheets.Add
  

То же самое с Excel.Workbook :

 Set excelBook = Excel.Application.Workbooks.Add
  

Существуют и другие способы (например, копирование существующего Worksheet без указания Target аргумента создаст новый Workbook , содержащий копию этого источника Worksheet ), но эмпирическое правило: если вы не можете New создать класс в библиотеке типов, на которую ссылается ссылка, мало шансов CreateObject сделать что-то лучше (если только регистрация типа явно не предотвращает раннее-использование привязки).


Вопрос был отредактирован, но этот ответ остается в силе: не используйте CreateObject для создания экземпляров классов, которые уже разрешены и легко доступны.

 Set objXml = New MSXML2.DOMDocument60 'works fine
  

Если вы действительно хотите использовать CreateObject , вам нужно использовать строки ProgID, которые существуют в вашем реестре.

 Set objXml = CreateObject("MSXML2.DOMDocument60") ' blows up on my machine as well
Set objXml = CreateObject("MSXML2.DOMDocument") ' works fine
  

Но использование CreateObject для создания экземпляра класса, о котором компилятор уже знает, является очень, очень обходным способом сделать это.

Комментарии:

1. Привет, Матье, подход с ключевым словом «New» работает для меня. Однако ни один из примеров CreateObject не работает для меня. Я знаю, что я получил это для работы на других компьютерах, и, основываясь на других примерах, этот подход работает для других людей. Мне бы очень хотелось знать, почему это не работает с моей текущей машиной, но пока я продолжу использовать вместо этого метод «New». Спасибо за вашу помощь.

2. Как CreateObject это работает, так это то, что он принимает предоставленную строку ProgID (или класс GUID), находит этот ProgID / GUID в реестре, находит библиотеку типов на диске, находит тип внутри этой библиотеки, создает его экземпляр и передает его вызывающему. Если он работает где-то еще, но не на вашем компьютере, вам может потребоваться восстановить / переустановить все, что установлено в библиотеке, которую вы используете. Раннее связывание загружает библиотеку типов и связывает типы и вызовы элементов во время компиляции (отсюда «eary») — предпочитайте раннее связывание, когда можете.