关于VBA中获取MicroFocus Rumba活动RDE对象的技术问询
解决MicroFocus Rumba实例重新获取的问题
我完全懂你碰到的这个麻烦——当Excel宏结束销毁了关联的Rumba对象后,想用GetObject(,"MicroFocus.Rumba")找回已经在运行的实例,结果却弹出“ActiveX无法创建组件”的错误。这个问题确实和Rumba的COM对象注册机制有关,给你几个可行的解决思路:
方案1:通过Rumba会话文件路径获取实例
如果用户打开的Rumba实例是基于某个会话文件(比如.rsf格式),可以直接通过文件路径来绑定实例,这种方式绕开了直接通过ProgID获取的限制:
Dim rumbaInstance As Object ' 替换成实际的Rumba会话文件路径 Set rumbaInstance = GetObject("C:\Your\Rumba\Session\Path\MySession.rsf")
Rumba的会话文件和运行实例是绑定的,只要实例处于运行状态,就能通过这种方式成功关联到它。
方案2:通过窗口句柄找回Rumba实例
在宏首次初始化Rumba时,提前记录它的窗口句柄,后续可以通过Windows API调用根据句柄重新获取COM对象:
- 先在模块顶部声明所需的API函数:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare Function ObjectFromLresult Lib "oleacc" _ (ByVal lResult As Long, ByVal riid As Any, ByVal wParam As Long, _ ppvObject As Any) As Long Private Declare Function SendMessageTimeout Lib "user32" Alias "SendMessageTimeoutA" _ (ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, _ ByVal lParam As Long, ByVal fuFlags As Long, ByVal uTimeout As Long, _ lpdwResult As Long) As Long Private Const SMTO_ABORTIFHUNG = &H2 Private Const WM_GETOBJECT = &H3D ' 定义GUID结构用于匹配Rumba对象 Private Type GUID Data1 As Long Data2 As Integer Data3 As Integer Data4(0 To 7) As Byte End Type
- 首次初始化Rumba时保存窗口句柄:
Global g_RumbaHWND As Long Global g_RumbaObj As Object Sub InitializeRumba() Set g_RumbaObj = CreateObject("MicroFocus.Rumba") ' 用Spy++工具确认Rumba的窗口类名,这里是示例值 g_RumbaHWND = FindWindow("Rumba Main Window Class", g_RumbaObj.SessionName) End Sub
- 需要重新获取实例时,通过句柄找回:
Sub RetrieveRumbaInstance() Dim objRumba As Object Dim rumbaIID As GUID Dim lResult As Long If g_RumbaHWND = 0 Then Exit Sub ' 设置Rumba对象的IID,可通过OLE/COM Object Viewer工具查询MicroFocus.Rumba的IID rumbaIID.Data1 = &H2D000000 rumbaIID.Data2 = &H0000 rumbaIID.Data3 = &H0000 rumbaIID.Data4(0) = &HC0 rumbaIID.Data4(1) = &H00 rumbaIID.Data4(2) = &H00 rumbaIID.Data4(3) = &H00 rumbaIID.Data4(4) = &H00 rumbaIID.Data4(5) = &H00 rumbaIID.Data4(6) = &H00 rumbaIID.Data4(7) = &H46 lResult = SendMessageTimeout(g_RumbaHWND, WM_GETOBJECT, 0, 0, SMTO_ABORTIFHUNG, 1000, lResult) If lResult <> 0 Then Call ObjectFromLresult(lResult, rumbaIID, 0, objRumba) Set g_RumbaObj = objRumba End If End Sub
方案3:修改“End”逻辑,避免销毁全局对象
如果业务逻辑允许,不要在宏结束时直接销毁全局Rumba对象,而是改为断开会话但保留实例:
Sub EndCurrentSession() ' 不要执行 Set g_RumbaObj = Nothing,而是调用Rumba的断开方法(假设存在) g_RumbaObj.Disconnect End Sub Sub ResumeWorkflow() ' 需要继续时直接重新连接会话(假设Rumba有Connect方法) g_RumbaObj.Connect End Sub
这样就无需重新获取实例,直接复用原来的对象即可。
为什么GetObject(,"MicroFocus.Rumba")会失败?
你推测的方向是对的,有些COM对象在由VB/VBA创建后,不会注册到系统的Running Object Table(ROT)中,导致GetObject无法通过ProgID找到它们。Rumba恰好属于这类对象,所以只能通过文件关联或者窗口句柄的方式来定位已运行的实例。
内容的提问来源于stack exchange,提问作者Samantha
相关产品推荐
相关产品推荐

