VBA for Access,运行时错误 451:未定义属性让过程和属性获取过程未返回对象

Posted

技术标签:

【中文标题】VBA for Access,运行时错误 451:未定义属性让过程和属性获取过程未返回对象【英文标题】:VBA for Access, run-time error 451: Property let procedure not defined and property get procedure did not return an object 【发布时间】:2012-11-20 16:42:04 【问题描述】:

所以我有一个对象的私有变量,它是一个数组:o_exception,声明为:

Private o_exception() as string

我可以在初始化它的值时对其进行全面测试:下限、上限、值,一切正常。

我正在尝试定义一个 let 属性,以便能够从对象外部访问数组的值:

Property Get exception()
On Error GoTo ERREUR
exception = o_exception
On Error GoTo 0
End Property

我仍然完全能够将我的属性识别为一个数组:

lbound(myObject.exception) is available
ubound(myObject.exception) is available
isArray(myObject.exception) returns a yes

但是

myObject.exception(0) 

给我以下错误:

run-time error 451: Property let procedure not defined and property get procedure did not return an object

我没有 let,因为我不需要它,而且我有非常相似的代码在其他对象上以相同的结构运行。我现在唯一的线索是,由于 myObject 被定义为另一个对象(集合)的成员,我必须通过键入来访问它:

myCollection.myObject.exception(0)

顺便说一句,将 Property Get 替换为 Public Function 会产生同样的错误...

【问题讨论】:

【参考方案1】:

几点说明:

无法使用您提供的信息复制您的问题,访问 Property Get 返回的数组应该可以工作(下面的代码可以正常工作)。 但是,错误消息表明解释器正在将您的代码视为作业,因此上下文可能很重要,您的问题中肯定缺少某些内容。

由于they are copied on assignment,数组的行为可能不会如您所愿,因此每次您引用myObject.exception 属性时,都会返回内部o_exception 数组的副本。 您实际上可以通过尝试更改数组的内容并意识到它实际上根本没有改变来看到这一点:

'---------------------------------
' Class1 code '
'---------------------------------
Private o_exception() As String

Property Get exception()
    exception = o_exception
End Property

Private Sub class_initialize()
    ReDim Preserve o_exception(10)
    o_exception(0) = "qwerty"
    o_exception(1) = "azerty"
End Sub    

'---------------------------------
' Test module '
'---------------------------------
Public Sub test()
    Dim a As Class1
    Set a = New Class1

    Debug.Print TypeName(a.exception)

    Debug.Print LBound(a.exception)
    Debug.Print UBound(a.exception)
    Debug.Print IsArray(a.exception)

    Debug.Print a.exception(0)
    a.exception(0) = "asdfg"
    Debug.Print a.exception(0)

    Dim s() As String
    s = a.exception()

    ' Print the memory address of the first string in each array '
    ' We could expect it to be the same, but they are not '
    Debug.Print StrPtr(s(0))
    Debug.Print StrPtr(a.exception(0))

    ' just to prove the point '
    s(0) = "ZZZZZZZZ"
    Debug.Print s(0)
    Debug.Print a.exception(0)

End Sub

调用test 将打印:

Class1
String()
0
10
True
qwerty
qwerty    => Should be 123456!
296094084 
296093004 => Expected to be the same address  as above, it's not!
ZZZZZZZZ
qwerty    => Should be ZZZZZZZZ!

要解决该问题,您可以使用 Collection 或构造您的类以返回单个对象,而不是公开数组本身,例如:

' Just use myObject.exception(0) as one would expect '
Property Get exception(index As Long) As String
    exception = o_exception(index)
End Property

顺便说一句,由于您的代码看起来像是在处理错误管理,我衷心建议您看看vbWatchdog。它非常非常适合以全局方式管理 Access 中的错误(不附属于该产品,只是一个快乐的用户)。

【讨论】:

以上是关于VBA for Access,运行时错误 451:未定义属性让过程和属性获取过程未返回对象的主要内容,如果未能解决你的问题,请参考以下文章

MS ACCESS VBA 运行时错误'3021';使用 .MoveNext

Solidworks 2016 SaveAs Access VBA运行时错误438

带有子查询的 SQL 查询上的 MS Access VBA 运行时错误 3075

查找文件夹/子文件夹名称时 MS Access VBA 运行时错误“13”类型不匹配

运行时错误“3264”访问 2010 VBA

使用 VBA 从 Excel 打开和关闭 Access 数据库 - Access 宏错误