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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 16:41:03  来源:igfitidea点击:

VBA: Run time error '91'?

vba

提问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 ActiveWindowsupposed 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 Setkeyword 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 Letkeyword to assign values, and Setkeyword to assign references; the Leteventually was deprecated (although still needed for defining properties) and the Setremained, 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

SourceWindowis 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 Letstatementshould not be confused with the Letclause(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 Letor 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 Setkeyword was also deprecated in VB.net, and also why the VB.net syntax for defining properties has dropped the Letin 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,所以这种暧昧松懈强制不发生。