从Excel中,我挂钩Glink OLE对象 - 这个对象是我需要与之交互的正在运行的程序,因此程序将(并且必须)在运行此代码之前已经打开。
由于(我假设)本地配置超出了我的范围或某些我不理解的API行为,有时代码会创建一个新对象而不是Get
- 已经开放了。就其本身而言,这不是最糟糕的事情 - 它可以解决。
如果我手动运行一个不包含任何循环或尝试枚举的Sub
,我可能会挂钩打开的对象(正确)或者生成相同类型的新的不可用对象(false) 。如果我勾选错误的一个,只需重新运行Sub
给我正确的对象 - 这是一致的。
如果我运行一个循环自身的Sub
(尝试通过手动重新运行sub来复制行为),没有这样的运气 - 它给了我“相同”的对象(不是真正相同的对象 - 它每次都会生成一个新实例,但无论如何,这将永远不会是正确的对象,因为正确的已经存在)一遍又一遍。
我有一些代码:
Dim gl As Glink.Auto
Set gl = Nothing
Set gl = GetObject("", "Glink.Auto")
这正如上面第2段所述 - 它可以在我不需要/不能使用的某个对象和我想要的对象之间可靠地交替,所以通过运行发现正确的对象是微不足道的宏可以是1或2倍,具体取决于第一次运行的结果。
有两种方法可以区分我是否得到了正确的对象:第一种方法是检查Instance
属性,所以我的代码包括一个检查:
Debug.Print gl.Instance
如果我有正确的对象,Instance
将是0
。相反,如果Instance
不是0
,那么我就会得到一些无法使用的内容。
第二个是Automated
。如果这是TRUE
,则该对象是通过OLE生成的(因此对我来说无法使用)。相反,如果是FALSE
,我知道它是指我手动打开的对象(这是我想要的对象)。
最终代码
将strict
设置为TRUE
可启用循环。手动运行和程序循环运行在代码中没有区别,除了标记为手动的运行strict = False
,而其他运行strict = True
。
' Glink globals
Global gl As glink.Auto
Global scr As IAutoScreen
' Other globals
Global dbg As Boolean
Global strict As Boolean
Sub Glink_Initialize()
Dim retryCount As Integer
retryCount = 0
dbg = True
strict = False
' Start GLINK session hook
Retry:
Set gl = Nothing
Set gl = GetObject("", "Glink.Auto")
If dbg = True Then
If Err.Number <> 0 Then
GoTo Terminate:
Else
If gl.Instance <> 0 And strict = True Then
If retryCount < 5 Then
If dbg = True Then
Debug.Print "No valid instance found, retrying."
Debug.Print "Instance: " & gl.Instance & " RetryCount: " & retryCount & vbCr
End If
retryCount = retryCount + 1
GoTo Retry:
ElseIf strict = True Then
If dbg = True Then Debug.Print "RetryCount exceeded limit"
GoTo Terminate:
End If
End If
Debug.Print "Image: " & gl.Caption & vbCr & "Instance: " & gl.Instance & vbCr & "Automation: " & gl.Automated
End If
End If
' End GLINK session hook
Exit Sub
Terminate:
Debug.Print "No Glink detected! Terminating."
Set gl = Nothing
End Sub
以下是两个手动运行(无循环)之后的一些调试语句
' Run 1
Image: GLINK - (ref.:2242.2853:ErgoIntegration)
Instance: 49 ' <-- Unusable object
Automation: True ' <-- Spawned by OLE
' Run 2
Image: GLINK - Vegard - AA90
Instance: 0 ' <-- Usable object
Automation: False ' <-- Not spawned by OLE = this is the object I want
这个过程会以绝对的一致性重复出现。获取正确的对象,生成新对象,获取正确的对象,生成新对象等:
Image: GLINK - (ref.:2242.2853:ErgoIntegration)
Instance: 56
Automation: True
Image: GLINK - Vegard - AA90
Instance: 0
Automation: False
Image: GLINK - (ref.:2242.2853:ErgoIntegration)
Instance: 57
Automation: True
Image: GLINK - Vegard - AA90
Instance: 0
Automation: False
Image: GLINK - (ref.:2242.2853:ErgoIntegration)
Instance: 58
Automation: True
Image: GLINK - Vegard - AA90
Instance: 0
Automation: False
以下是包含循环
的1代代码的调试语句No valid instance found, retrying.
Instance: 43 RetryCount: 0
No valid instance found, retrying.
Instance: 44 RetryCount: 1
No valid instance found, retrying.
Instance: 45 RetryCount: 2
No valid instance found, retrying.
Instance: 46 RetryCount: 3
No valid instance found, retrying.
Instance: 47 RetryCount: 4
所以似乎使用程序化循环跳过了找到正确对象的步骤......为什么?有办法解决这个问题吗?
答案 0 :(得分:0)
根据@Flephal的评论和MSDN,人们会认为省略body {
background: url('../images/oops.jpg');
background-repeat: no-repeat;
background-size: 100% 100% ;
}
的第一个参数将是正确的方法。出于某种原因,我没有经历过这种情况 - 如果第一个参数不存在,有时会出现429错误。
更具体地说,这是来自MSDN的内容:
如果pathname是零长度字符串(&#34;&#34;),则GetObject返回一个新字符串 指定类型的对象实例。如果pathname参数是 省略,GetObject返回指定的当前活动对象 类型。如果不存在指定类型的对象,则会发生错误。
根据这个描述,我假设我得到了引用的错误,因为找不到指定的对象(但是我正在查看它的窗口,所以我知道它在那里)。我不知道为什么会这样,但是:
解决方法强>
更改此内容:
GetObject
到此:
Set gl = Nothing
Set gl = GetObject("", "Glink.Auto")
并添加此功能:
Set gl = Nothing
Set gl = GlinkObjectHook