VBA:运行时错误“91”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18927297/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
VBA: Run time error '91'?
提问by supercheetah
All I'm trying to do here is save a reference to the currently active window, but it doesn't seem to be working. It gives me a run time error on the last line.
我在这里要做的就是保存对当前活动窗口的引用,但它似乎不起作用。它在最后一行给了我一个运行时错误。
Dim SourceWindow As Window, QACheckWindow As Window
SourceWindow = ActiveWindow
I'm not exactly sure why. Isn't ActiveWindow
supposed to return the currently active window? If not, how can I make a reference to it?
我不确定为什么。不ActiveWindow
应该返回当前活动的窗口吗?如果没有,我如何引用它?
EDIT: The above is right at the beginning of my function, so all there is before it is Sub FuncName()
编辑:上面是我函数的开头,所以在它之前的所有内容 Sub FuncName()
回答by Mathieu Guindon
In VB object variables require the Set
keyword to be assigned. Object properties that are objects also need to be Set
. Runtime error 91 "object variable not set" is raised when the assignment doesn't use that keyword.
在 VB 中,对象变量需要Set
分配关键字。作为对象的对象属性也需要是Set
. 当赋值不使用该关键字时,会引发运行时错误 91“未设置对象变量”。
This is inherited from legacy Let
keyword to assign values, and Set
keyword to assign references; the Let
eventually was deprecated (although still needed for defining properties) and the Set
remained, leaving the VB6/VBA value assignment syntax like [Let] variable = value
, where "Let" is optional.
这是从 legacyLet
关键字继承来分配值,以及Set
关键字来分配引用;在Let
最终被弃用(尽管仍然需要定义属性)和Set
留,留下VB6 / VBA赋值语法一样[Let] variable = value
,其中“让”是可选的。
In the declaration and assignment:
在声明和赋值中:
Dim SourceWindow As Window, QACheckWindow As Window
'this is like saying "Let SourceWindow = ActiveWindow":
SourceWindow = ActiveWindow
SourceWindow
is an object, assigned as if it were a value- this causes VBA to attempt let-coercionthrough a default member call. If the object wasn't initialized, the member call fails with error 91. If the object was initialized but doesn't have a default member, error 438 is raised.
SourceWindow
是一个对象,就像一个值一样分配- 这会导致 VBA 尝试通过默认成员调用进行let-coercion。如果对象未初始化,则成员调用失败并返回错误 91。如果对象已初始化但没有默认成员,则会引发错误 438。
So in this case error 91 is being raised because of an implicit member call; the .net equivalent would be a NullReferenceException
:
因此,在这种情况下,由于隐式成员调用而引发错误 91;.net 等价物将是NullReferenceException
:
Dim SourceWindow As Window, Dim WindowTitle As String
'"SourceWindow" reference isn't set, the object can't be accessed yet:
WindowTitle = SourceWindow.Caption
I'm going to go a bit overboard here, but the legacy Let
statementshould not be confused with the Let
clause(in VB.net) which, in the LINQ query syntax(in VB.net), computes a value and assigns it to a new, query-scoped variable (example taken from MSDN):
我在这里有点过火,但遗留Let
语句不应与Let
子句(在 VB.net 中)混淆,后者在 LINQ查询语法(在 VB.net 中)计算一个值并将其分配给新的、查询范围的变量(来自MSDN 的示例):
From p In products
Let Discount = p.UnitPrice*0.1 '"Discount" is only available within the query!
Where Discount >= 50
Select p.ProductName, p.UnitPrice, Discount
VB.net assigns both valuesand references, without the need to specify a Let
or a Set
, because in .net this distinction is a much thinner line, given how everything ultimately derives from System.Object
... including System.ValueType
. That's why the Set
keyword was also deprecated in VB.net, and also why the VB.net syntax for defining properties has dropped the Let
in favor of Set
- because parameterless default membersare illegal in VB.NET, so this ambiguous let-coerciondoesn't happen.
VB.net 分配值和引用,无需指定 aLet
或 a Set
,因为在 .net 中,这种区别是一条更细的线,考虑到一切最终是如何派生自System.Object
... 包括System.ValueType
. 这就是为什么该Set
关键词在VB.net也被弃用,并且也是为什么VB.net语法定义属性已经下降了Let
赞成的Set
-因为参数的默认成员是非法在VB.NET,所以这种暧昧松懈强制不发生。