VBA CreateObject 无法在 64 位上创建 ActiveX 组件 Windows
VBA CreateObject can’t create ActiveX component on 64Bit Windows
我必须在 Visual Studio 2013 年编写一个程序,但它不起作用,所以我开始使用 Microsoft Excel 及其开发平台测试所有可能性。我从以下版本开始(由提供我需要使用的程序的公司提供):
Sub Main()
Dim XServer As X2000.Server
Dim XApp As X2000.Application
Dim XSR As X2000.ScriptRoutines
Set XServer = New X2000.Server
Set XApp = XServer.AppConnection() '<- This actually fires the application
XApp.Visible = True
Set XSR = XApp.ScriptCommands
XSR.DATA_FILENAME = "C:\X2000\myFile.x" ' <- Code blocks here
End Sub
这基本上启动了应用程序 X2000.exe,将我的代码连接到它,然后通过在程序中加载 myFile.x
来执行 DATA_FILENAME
分配例程。我需要启动应用程序,因为那时它的许可证已经过检查,我没有任何其他选项可以使用。
现在,在这个版本中,代码在没有任何其他信息的情况下通过说 "A dll is missing" 阻塞在最后一行。我尝试通过执行以下操作来延迟绑定 ScriptRoutines
对象:
Dim XServer As X2000.Server
Dim XApp As X2000.Application
Dim XSR As Object
Set XServer = New X2000.Server
Set XApp = XServer.AppConnection()
XApp.Visible = True
XSR = CreateObject("XApp.ScriptCommands")
这也行不通,但确实给了我更多信息:"ActiveX control couldn’t load the object"。我做了一些研究,通过 "Dependancy Walker" 发现 X2000.exe
依赖于 MSVBVM60.DLL
,system32
文件夹中缺少它。不过很好奇,因为我的系统是 64 位的,Excel 也是,我通过使用 32 位兼容性在 VS2013 上尝试了代码,但代码仍然不起作用。
我在包含此文件的位置安装了 the service pack from Microsoft,却发现 system32
未被触及...
sysWoW64
而不是已经有一个 MSVBVM60.DLL
,因此我怀疑 X2000.exe
只是为了在 32 位系统上工作而编写的:我错了。
我的一位同事可以执行用 MATLAB 代码编写的相同程序:
function [Data,eng_or_met] = Read_X2000_File_BB_2(sFileName)
XServer = actxserver('X2000.server');
XApp = XServer.AppConnection;
XApp.Visible = 1;
objX2000 = XApp.ScriptCommands;
objX2000.data_filename = "C:\X2000\myFile.x";
delete(XServer);
由于 actxserver
function,我相信它可以处理此兼容性问题。
如何对 Excel/VS2013 执行相同的操作?
编辑:
我尝试了 omegastripes 建议的代码:
Dim XSR As Object
Set XSR = CreateObjectx86("XApp.ScriptCommands") ' create ActiveX via x86 mshta host
作为CreateObjectx86
函数linked here。我尝试了两个 If / Else
条件,但最后无论如何都没有创建对象,两者都是:
Set CreateObjectx86 = oWnd.CreateObjectx86(sProgID)
和
Set CreateObjectx86 = CreateObject(sProgID)
如果我不更改代码(因此不会 #If Win64
),最后一行是执行的内容。
编辑:
根据这个问题的第一个答案,我也试过:
Dim XServer As Object
Dim XApp As X2000.Application
Dim XSR As X2000.Script
Set XServer = CreateObject("X2000.Server")
Set XApp = XServer.AppConnection()
XApp.Visible = True
Set XSR = X2000.ScriptCommands
才发现我得到了同样的错误。
我显然解决了这个问题。受 Hans Passant 的启发,我 Dim
将 XServer
编辑为唯一依赖于对 X2000.exe 的引用的对象:
Dim XServer As X2000.Server
Dim XApp As Object
Dim XSR As Object
Set XServer = New X2000.Server
Set XApp = XServer.AppConnection
XApp.Visible = True
Set XSR = XApp.ScriptCommands
XSR.DATA_FILENAME = "C:\foo.x"
DATA_FILENAME
实际上是一个被执行的"ScriptCommand"。
就这么简单。但是我不知道为什么会这样。
我必须在 Visual Studio 2013 年编写一个程序,但它不起作用,所以我开始使用 Microsoft Excel 及其开发平台测试所有可能性。我从以下版本开始(由提供我需要使用的程序的公司提供):
Sub Main()
Dim XServer As X2000.Server
Dim XApp As X2000.Application
Dim XSR As X2000.ScriptRoutines
Set XServer = New X2000.Server
Set XApp = XServer.AppConnection() '<- This actually fires the application
XApp.Visible = True
Set XSR = XApp.ScriptCommands
XSR.DATA_FILENAME = "C:\X2000\myFile.x" ' <- Code blocks here
End Sub
这基本上启动了应用程序 X2000.exe,将我的代码连接到它,然后通过在程序中加载 myFile.x
来执行 DATA_FILENAME
分配例程。我需要启动应用程序,因为那时它的许可证已经过检查,我没有任何其他选项可以使用。
现在,在这个版本中,代码在没有任何其他信息的情况下通过说 "A dll is missing" 阻塞在最后一行。我尝试通过执行以下操作来延迟绑定 ScriptRoutines
对象:
Dim XServer As X2000.Server
Dim XApp As X2000.Application
Dim XSR As Object
Set XServer = New X2000.Server
Set XApp = XServer.AppConnection()
XApp.Visible = True
XSR = CreateObject("XApp.ScriptCommands")
这也行不通,但确实给了我更多信息:"ActiveX control couldn’t load the object"。我做了一些研究,通过 "Dependancy Walker" 发现 X2000.exe
依赖于 MSVBVM60.DLL
,system32
文件夹中缺少它。不过很好奇,因为我的系统是 64 位的,Excel 也是,我通过使用 32 位兼容性在 VS2013 上尝试了代码,但代码仍然不起作用。
我在包含此文件的位置安装了 the service pack from Microsoft,却发现 system32
未被触及...
sysWoW64
而不是已经有一个 MSVBVM60.DLL
,因此我怀疑 X2000.exe
只是为了在 32 位系统上工作而编写的:我错了。
我的一位同事可以执行用 MATLAB 代码编写的相同程序:
function [Data,eng_or_met] = Read_X2000_File_BB_2(sFileName)
XServer = actxserver('X2000.server');
XApp = XServer.AppConnection;
XApp.Visible = 1;
objX2000 = XApp.ScriptCommands;
objX2000.data_filename = "C:\X2000\myFile.x";
delete(XServer);
由于 actxserver
function,我相信它可以处理此兼容性问题。
如何对 Excel/VS2013 执行相同的操作?
编辑:
我尝试了 omegastripes 建议的代码:
Dim XSR As Object
Set XSR = CreateObjectx86("XApp.ScriptCommands") ' create ActiveX via x86 mshta host
作为CreateObjectx86
函数linked here。我尝试了两个 If / Else
条件,但最后无论如何都没有创建对象,两者都是:
Set CreateObjectx86 = oWnd.CreateObjectx86(sProgID)
和
Set CreateObjectx86 = CreateObject(sProgID)
如果我不更改代码(因此不会 #If Win64
),最后一行是执行的内容。
编辑:
根据这个问题的第一个答案,我也试过:
Dim XServer As Object
Dim XApp As X2000.Application
Dim XSR As X2000.Script
Set XServer = CreateObject("X2000.Server")
Set XApp = XServer.AppConnection()
XApp.Visible = True
Set XSR = X2000.ScriptCommands
才发现我得到了同样的错误。
我显然解决了这个问题。受 Hans Passant 的启发,我 Dim
将 XServer
编辑为唯一依赖于对 X2000.exe 的引用的对象:
Dim XServer As X2000.Server
Dim XApp As Object
Dim XSR As Object
Set XServer = New X2000.Server
Set XApp = XServer.AppConnection
XApp.Visible = True
Set XSR = XApp.ScriptCommands
XSR.DATA_FILENAME = "C:\foo.x"
DATA_FILENAME
实际上是一个被执行的"ScriptCommand"。
就这么简单。但是我不知道为什么会这样。