【问题标题】:VBA for Access, run-time error 451: Property let procedure not defined and property get procedure did not return an objectVBA for Access,运行时错误 451:未定义属性让过程和属性获取过程未返回对象
【发布时间】: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 会产生同样的错误...

【问题讨论】:

    标签: vba ms-access


    【解决方案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 中的错误(不附属于该产品,只是一个快乐的用户)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-06
      • 2021-11-10
      相关资源
      最近更新 更多