Получение ScriptControl для работы с Excel 2010 x64
Я пытаюсь использовать решение, данное этому , однако, всякий раз, когда я пытаюсь запустить самое основное, я получаю ошибку Object not Defined
. Я думал, что это будет моя ошибка (не установив ScriptControl). Однако я попытался установить, как описано здесь , безрезультатно.
Я использую Windows 7 Professional x64 с Office 2010 64 бит.
- Как создать пользовательское меню «Shapes» в Powerpoint
- Прокрутите каждую таблицу на веб-странице javascrape с помощью макроса VBA
- Оператор VBA «И» оценивает второй аргумент, когда первый является ложным?
- Любая функция Excel, которая изменит строку?
- Получение ошибки Процедура слишком велика в макросах VBA (Excel)
- Как можно выделить две отдельные ячейки с разделенными запятыми данными и соединить их?
- Редактор VBA автоматически удаляет пробелы на концах строк
- Совместный интерфейс COM с C # и VBA
- Скрытые особенности VBA
- Что такое .NumberFormat Options В Excel VBA?
- VBA Macro для сравнения всех ячеек двух файлов Excel
- Экспортировать изображения из файла excel в jpg с помощью VBA
- Объединение данных ячейки в другие данные, если значения соответствуют
К сожалению, scriptcontrol является 32-битным компонентом и не будет работать внутри 64-битного процесса.
Вы можете создавать объекты ActiveX, такие как ScriptControl
, которые доступны в 32-разрядных версиях Office с помощью хоста mshta x86 в 64-разрядной версии VBA, вот пример (поместите код в стандартный модуль проекта VBA):
Option Explicit Sub Test() Dim oSC As Object Set oSC = CreateObjectx86("ScriptControl") ' create ActiveX via x86 mshta host Debug.Print TypeName(oSC) ' ScriptControl ' do some stuff CreateObjectx86 Empty ' close mshta host window at the end End Sub Function CreateObjectx86(sProgID) Static oWnd As Object Dim bRunning As Boolean #If Win64 Then bRunning = InStr(TypeName(oWnd), "HTMLWindow") > 0 If IsEmpty(sProgID) Then If bRunning Then oWnd.Close Exit Function End If If Not bRunning Then Set oWnd = CreateWindow() oWnd.execScript "Function CreateObjectx86(sProgID): Set CreateObjectx86 = CreateObject(sProgID): End Function", "VBScript" End If Set CreateObjectx86 = oWnd.CreateObjectx86(sProgID) #Else If Not IsEmpty(sProgID) Then Set CreateObjectx86 = CreateObject(sProgID) #End If End Function Function CreateWindow() ' source http://forum.script-coding.com/viewtopic.php?pid=75356#p75356 Dim sSignature, oShellWnd, oProc On Error Resume Next sSignature = Left(CreateObject("Scriptlet.TypeLib").GUID, 38) CreateObject("WScript.Shell").Run "%systemroot%\syswow64\mshta.exe about:"" """, 0, False Do For Each oShellWnd In CreateObject("Shell.Application").Windows Set CreateWindow = oShellWnd.GetProperty(sSignature) If Err.Number = 0 Then Exit Function Err.Clear Next Loop End Function
У него мало недостатков: необходим отдельный процесс mshta.exe
, который указан в диспетчере задач, и показано нажатие клавиши Alt + Tab hidden HTA:
Также вы должны закрыть это окно HTA в конце вашего кода с помощью CreateObjectx86 Empty
.
ОБНОВИТЬ
Вы можете автоматически закрыть окно хоста: создав экземпляр classа или активную трассировку mshta.
Первый метод предполагает, что вы создаете экземпляр classа в качестве оболочки, который использует Private Sub Class_Terminate()
для закрытия windows.
Примечание. Если Excel сработает во время выполнения кода, то нет завершения classа, поэтому окно останется в фоновом режиме.
Поместите приведенный ниже код в модуль classа cMSHTAx86Host
:
Option Explicit Private oWnd As Object Private Sub Class_Initialize() #If Win64 Then Set oWnd = CreateWindow() oWnd.execScript "Function CreateObjectx86(sProgID): Set CreateObjectx86 = CreateObject(sProgID) End Function", "VBScript" #End If End Sub Private Function CreateWindow() ' source http://forum.script-coding.com/viewtopic.php?pid=75356#p75356 Dim sSignature, oShellWnd, oProc On Error Resume Next sSignature = Left(CreateObject("Scriptlet.TypeLib").GUID, 38) CreateObject("WScript.Shell").Run "%systemroot%\syswow64\mshta.exe about:"" """, 0, False Do For Each oShellWnd In CreateObject("Shell.Application").Windows Set CreateWindow = oShellWnd.GetProperty(sSignature) If Err.Number = 0 Then Exit Function Err.Clear Next Loop End Function Function CreateObjectx86(sProgID) #If Win64 Then If InStr(TypeName(oWnd), "HTMLWindow") = 0 Then Class_Initialize Set CreateObjectx86 = oWnd.CreateObjectx86(sProgID) #Else Set CreateObjectx86 = CreateObject(sProgID) #End If End Function Function Quit() #If Win64 Then If InStr(TypeName(oWnd), "HTMLWindow") > 0 Then oWnd.Close #End If End Function Private Sub Class_Terminate() Quit End Sub
Поместите приведенный ниже код в стандартный модуль:
Option Explicit Sub Test() Dim oHost As New cMSHTAx86Host Dim oSC As Object Set oSC = oHost.CreateObjectx86("ScriptControl") ' create ActiveX via x86 mshta host Debug.Print TypeName(oSC) ' ScriptControl ' do some stuff ' mshta window is running until oHost instance exists ' if necessary you can manually close mshta host window by oHost.Quit End Sub
Второй метод для тех, кто по какой-то причине не хочет использовать classы. Дело в том, что окно mshta проверяет состояние переменной Static oWnd
VBA, вызывающей CreateObjectx86
без аргументов через внутреннюю функцию setInterval()
каждые 500 мс, и завершает работу, если ссылка потеряна (либо пользователь нажал кнопку Reset в окне VBA Project, либо книга была закрыто (ошибка 1004)).
Примечание: точки останова VBA (ошибка 57097), ячейки рабочих листов, отредактированные пользователем, открытые диалоговые модальные windows, такие как Open / Save / Options (ошибка -2147418111), приостанавливают трассировку, поскольку они делают приложение невосприимчивым к внешним вызовам из mshta. Такие исключения действий обрабатываются, и после завершения код будет продолжать работать, никаких сбоев.
Поместите приведенный ниже код в стандартный модуль:
Option Explicit Sub Test() Dim oSC As Object Set oSC = CreateObjectx86("ScriptControl") ' create ActiveX via x86 mshta host Debug.Print TypeName(oSC) ' ScriptControl ' do some stuff ' mshta window is running until Static oWnd reference to window lost ' if necessary you can manually close mshta host window by CreateObjectx86 Empty End Sub Function CreateObjectx86(Optional sProgID) Static oWnd As Object Dim bRunning As Boolean #If Win64 Then bRunning = InStr(TypeName(oWnd), "HTMLWindow") > 0 Select Case True Case IsMissing(sProgID) If bRunning Then oWnd.Lost = False Exit Function Case IsEmpty(sProgID) If bRunning Then oWnd.Close Exit Function Case Not bRunning Set oWnd = CreateWindow() oWnd.execScript "Function CreateObjectx86(sProgID): Set CreateObjectx86 = CreateObject(sProgID) End Function", "VBScript" oWnd.execScript "var Lost, App;": Set oWnd.App = Application oWnd.execScript "Sub Check(): On Error Resume Next: Lost = True: App.Run(""CreateObjectx86""): If Lost And (Err.Number = 1004 Or Err.Number = 0) Then close: End If End Sub", "VBScript" oWnd.execScript "setInterval('Check();', 500);" End Select Set CreateObjectx86 = oWnd.CreateObjectx86(sProgID) #Else Set CreateObjectx86 = CreateObject(sProgID) #End If End Function Function CreateWindow() ' source http://forum.script-coding.com/viewtopic.php?pid=75356#p75356 Dim sSignature, oShellWnd, oProc On Error Resume Next sSignature = Left(CreateObject("Scriptlet.TypeLib").GUID, 38) CreateObject("WScript.Shell").Run "%systemroot%\syswow64\mshta.exe about:"" """, 0, False Do For Each oShellWnd In CreateObject("Shell.Application").Windows Set CreateWindow = oShellWnd.GetProperty(sSignature) If Err.Number = 0 Then Exit Function Err.Clear Next Loop End Function
Для 32-битной версии элемента управления доступно 64-битное падение в замене. Google для управления скриптом Tabalacus. https://github.com/tablacus/TablacusScriptControl . Управление может быть скомпилировано с бесплатными версиями VS, если вам нужно.
В редакторе VBA откройте «Инструменты»> «Ссылки» и включите Microsoft Script Control.