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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13477881/
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-11 18:33:39  来源:igfitidea点击:

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

vbams-access

提问by Philippe Grondier

So I have one of my object's private variable which is an array: o_exception, declared as:

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

Private o_exception() as string

I can fully test it when initialising its values: lower bound, upper bound, values, everything is ok.

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

I am trying then to define a let property to be able to access the values of the array from outside the object:

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

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

I am still fully able to identify my property as an array:

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

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

But

myObject.exception(0) 

gives me the following error:

给了我以下错误:

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

I don't have a let, as I don't need it, and I have very similar code running with the very same structure on other objects. My only clue now is that, as myObject is defined as a member of another object (a collection), I must access it by typing:

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

myCollection.myObject.exception(0)

By the way, replacing the Property Get by a Public Function gives the very same error ...

顺便说一句,用公共函数替换 Property Get 会产生同样的错误......

回答by Renaud Bompuis

A couple of remarks:

几点说明:

  • Can't replicate your issue with the information you gave, accessing the array returned by the Property Getshould work (code below works fine).
    However, the error message is suggesting that the interpreter is considering your code as an assignment, so context may be important, there must be something that is missing from your question.

  • Arrays may not behave as you wish, since they are copied on assignment, so every time you refer to the myObject.exceptionproperty, a copy of the internal o_exceptionarray is returned.
    You can actually see that by trying to change the content of the array and realizing that it doesn't actually change at all:

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

  • 数组可能不会如您所愿,因为它们是在赋值时复制的,因此每次引用该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

Calling testwill print this:

调用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!

To solve that issue, you could use Collectionor construct your class to return individual objects instead of exposing the array itself, like:

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

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


Just in passing, since your code looks like you're dealing with error management, I can heartily recommend you have a look at vbWatchdog. It's really, really great for managing errors in Access in a global way (not affiliated with that product, just a happy user of it).

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