#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») — предпочитайте раннее связывание, когда можете.