gpt4 book ai didi

excel - VBA UserForm 为其参数之一提供运行时错误 91

转载 作者:行者123 更新时间:2023-12-04 21:19:23 30 4
gpt4 key购买 nike

我正在尝试通过 Sub 使用参数在 excel-VBA 中创建相同无模式用户窗体的多个实例。

我可以使用我要分配的三个参数中的两个使其工作,但第三个参数不断返回我

"Run-time Error '91': Object variable or With block variable not set"



我不知道为什么。
这可能是我没有看到的明显错字,但我真的无法指出问题所在。
这是我的代码:
Sub AskToClose(targetWksht As Worksheet, targetRow As Integer, test As String)
Dim newInstanceOfMe As Object

Set newInstanceOfMe = UserForms.Add("MOVE_TO_CLOSED") 'MOVE_TO_CLOSED is the name of my UserForm

newInstanceOfMe.targetWksht = targetWksht 'If I comment this line it works just fine, otherwise Run-time error 91
newInstanceOfMe.targetRow = targetRow
newInstanceOfMe.test = test

newInstanceOfMe.Show vbModeless
End Sub

_____________________________________________________________________

Sub test()
Dim openWksht As Worksheet

Set openWksht = Worksheets("OPEN WO") 'The worksheet exists and works just fine everywhere else

Call AskToClose(openWksht, 2, "test 2")
Call AskToClose(openWksht, 3, "test 3")
Call AskToClose(openWksht, 4, "test 4")

Set openWksht = Nothing 'I tried to comment this line just in case, same result...
End Sub

_____________________________________________________________________
'My MOVE_TO_CLOSED UserForm parameters
Public targetWksht As Worksheet
Public targetRow As Integer
Public test As String

最佳答案

newInstanceOfMe.targetWksht = targetWksht


此语句为 Value Required 生成错误级别的代码质量检查结果。 Rubberduck(我管理的一个开源 VBIDE 插件项目)中的检查。检查说明情况如下:

Object used where a value is required

The VBA compiler does not raise an error if an object is used in a place that requires a value type and the object's declared type does not have a suitable default member. Under almost all circumstances, this leads to a run-time error 91 'Object or With block variable not set' or 438 'Object doesn't support this property or method' depending on whether the object has the value 'Nothing' or not, which is harder to detect and indicates a bug.



VBA 中有两种类型的赋值:值赋值( Let)和引用赋值( Set)。 Let关键字对于值分配是多余的/可选的/过时的:
Dim foo As Long
foo = 2 + 2
Let foo = 2 + 2 '<~ exactly equivalent to the above

所以除非 Set存在关键字时,VBA 会尝试进行值分配。如果对象有一个默认成员,那可能会起作用——VBA 规范定义了 let-coercion 机制如何实现这一点。这就是您可以分配 Range 的方式为一个值:
Sheet1.Range("A1") = 42

这是隐式分配给 Range.Value ,通过对 Range.[_Default] 的隐式成员调用, Range 的隐藏属性类(class)。

如果赋值的右手边也是一个对象,那么 let-coercion 将会发生在操作符的两边:
Sheet1.Range("A1") = Sheet1.Range("B1") '<~ implicit default member calls galore!
Sheet1.Range("A1").Value = Sheet1.Range("B1").Value

但我们不是在看 Range在这里,我们正在查看 UserForm , 和 UserForm没有默认成员,所以 let-coercion 不会发生......但编译器不会验证这一点,所以代码无论如何都会运行......而是在运行时爆炸。

因此,我们正在查看 Let对于没有定义默认成员的类类型,双方都持有一个对象引用的赋值。
Something.SomeObject = someOtherObject

但是 VBA 不在乎没有默认成员 - 因为没有 Set关键字,它会尽其所能做你告诉它做的事情,并将这些对象强制转换为值......并且显然失败了。

如果 Something.SomeObject (左侧)是 Nothing ,那么 let-coercion 尝试将尝试调用不存在的默认成员 -- 但由于对象引用是 Nothing ,调用无效,并引发错误 91。

如果 Something.SomeObject已经持有一个有效的对象引用,那么 let-coercion 尝试将更进一步,并失败并出现错误 438,因为没有要调用的默认成员。

如果 Something.SomeObject有一个默认成员(并且引用不是 Nothing ),然后值分配成功,没有引发错误......但没有分配对象引用,这可能是一个微妙的错误!

添加 Set关键字使分配成为引用分配,现在一切正常。

关于excel - VBA UserForm 为其参数之一提供运行时错误 91,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58733770/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com