我試圖使用this給出的解決方案,但是,每當我嘗試運行最基本的任何事情時,都會收到Object not Defined
錯誤。我認爲這將是我的錯(沒有安裝ScriptControl)。但是,我試圖按照here中的描述安裝,無濟於事。獲取ScriptControl使用Excel 2010 x64
我使用Office 2010 64位版本運行Windows 7 Professional x64。
我試圖使用this給出的解決方案,但是,每當我嘗試運行最基本的任何事情時,都會收到Object not Defined
錯誤。我認爲這將是我的錯(沒有安裝ScriptControl)。但是,我試圖按照here中的描述安裝,無濟於事。獲取ScriptControl使用Excel 2010 x64
我使用Office 2010 64位版本運行Windows 7 Professional x64。
不幸的是,scriptcontrol只是一個32位組件,不會在64位進程中運行。
在VBA編輯器上,轉至工具>參考並啓用Microsoft腳本控制。
您可以創建ActiveX對象,如ScriptControl
,它在通過對64位VBA版本MSHTA的x86主機32位Office版本,這裏是例子(把一個標準的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:""<head><script>moveTo(-32000,-32000);document.title='x86Host'</script><hta:application showintaskbar=no /><object id='shell' classid='clsid:8856F961-340A-11D0-A96B-00C04FD705A2'><param name=RegisterAsBrowser value=1></object><script>shell.putproperty('" & sSignature & "',document.parentWindow);</script></head>""", 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鍵+標籤隱藏 HTA窗口:
此外,您必須在代碼末尾關閉HTA窗口CreateObjectx86 Empty
。
UPDATE
您可以將自動關閉主窗口:通過創建類的實例或MSHTA積極跟蹤。
第一種方法假定您創建一個類實例作爲包裝,它使用Private Sub Class_Terminate()
來關閉窗口。
注意:如果Excel在執行代碼時崩潰,那麼沒有類終止,因此窗口將保留在後臺。
把下面的代碼在名爲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:""<head><script>moveTo(-32000,-32000);document.title='x86Host'</script><hta:application showintaskbar=no /><object id='shell' classid='clsid:8856F961-340A-11D0-A96B-00C04FD705A2'><param name=RegisterAsBrowser value=1></object><script>shell.putproperty('" & sSignature & "',document.parentWindow);</script></head>""", 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
方法二對於那些不希望誰出於某種原因使用類。問題是,mshta窗口每隔500毫秒檢查VBA的Static oWnd
變量Static oWnd
變量的調用CreateObjectx86
的狀態,通過內部setInterval()
函數沒有參數,如果參考丟失(用戶在VBA項目窗口中按下了重置,或者工作簿已關閉(錯誤1004))。注意:由用戶編輯的工作表單元格的VBA斷點(錯誤57097)打開了對話框模式窗口,如打開/保存/選項(錯誤-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:""<head><script>moveTo(-32000,-32000);document.title='x86Host'</script><hta:application showintaskbar=no /><object id='shell' classid='clsid:8856F961-340A-11D0-A96B-00C04FD705A2'><param name=RegisterAsBrowser value=1></object><script>shell.putproperty('" & sSignature & "',document.parentWindow);</script></head>""", 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
哇,很酷。 – 2016-07-23 21:54:21
驚人的解決方案,它應該是被接受的答案,你認爲有一種方法可以在宏的末尾自動關閉窗口? – gbaccetta 2016-08-25 12:06:00
@gbaccetta我發佈了窗戶自鎖的解決方案。 – omegastripes 2016-10-03 21:22:03
爲了有用,我們就需要看你嘗試過確切的代碼,並得到了錯誤(和從中行代碼的) – 2012-03-15 18:53:55
蒂姆 - 我有同樣的問題。我使用Codo接受答案的確切代碼來鏈接問題(從這個問題的最上面一行連接)。當運行TestJSONAccess Sub時,我從InitScriptEngine子句的第一行(Set ScriptEnging = New ScriptControl)收到一個錯誤,提示「運行時錯誤'429':ActiveX組件無法創建對象」。我已經將引用設置爲msscript.ocx文件。 – 2012-03-21 17:10:40