为什么VBA Me关键字无法在其自己的模块中访问私有过程?

时间:2009-12-13 05:25:14

标签: vba scope encapsulation

我刚刚发现Me关键字无法访问私有过程,即使它们位于自己的类模型中也是如此。

在Class1中使用以下代码:

Private Sub Message()
    Debug.Print "Some private procedure."
End Sub

Public Sub DoSomething()
    Me.Message
End Sub

此代码实例化类的实例:

Sub TestClass()
    Dim objClass As New Class1
    objClass.DoSomething
End Sub

Me.Message抛出编译错误“找不到方法或数据成员。”

如果我将Private Sub Message()更改为Public,则该过程正常。我也可以从DoSomething过程中删除Me关键字,但我的印象是Me关键字背后的想法是确保Class1的多个实例被正确封装。

为什么VBA Me关键字在私有时无法在自己的模块中访问?省略Me关键字并在类中执行类似的操作是否安全?

Private Sub Message()
    Debug.Print "Some private procedure."
End Sub

Public Sub DoSomething()
    Message
End Sub

谢谢!

更新:感谢有关正确语法的提示,我的代码正常运行。我仍然在寻找为什么我可以在它自己的模块的实例中引用私有过程的解释。我找不到任何好的文件。

5 个答案:

答案 0 :(得分:6)

如果没有与设计师交谈,那么为什么设计这种方式的任何猜测都是纯粹的假设。但我自己的猜测是,Me关键字返回对代码当前正在执行的对象的引用。我猜想而不是为我创建一个特例,他们发现继续遵守范围规则更容易对象。也就是说object.method只能用于公共或朋友方法。所以我,就是它所说的,是当前正在执行的对象的一个​​实例。由于VBA / VB6没有共享方法,因此如果您使用Me加注,则无关紧要。

但如果它让你感觉更好,我发现它也令人难以置信的讨厌。

答案 1 :(得分:2)

您不需要Me关键字来调用自己的类。

答案 2 :(得分:1)

我是这个类对象实例。所以没有人可以直接调用私有子函数或函数或访问私有变量,除了这个类公共函数或子函数。

答案 3 :(得分:1)

s.server->'$[0]'

使用Call语句

使用私有类方法GroupAttack
Public Function Fight() As String
'performs a round of attacks i.e. each character from both sides performs an attack
'returns a scripted version of the outcomes of the round

'check if buccaneers are all dead
If mBuccaneers.aliveCount > 0 Then

    'check if any hostiles are alive
    If mHostiles.aliveCount > 0 Then

        'check we have some buccaneers
        If mBuccaneers.count = 0 Then
            Fight = "There are no buccaneers. Load or create some buccaneers"
        Else
            If mHostiles.count = 0 Then
                'can't fight
                Fight = "There are no hostiles to fight. Generate some hostiles"
            Else
                mScript = ""
                Call GroupAttack(mBuccaneers, mHostiles)
                Call GroupAttack(mHostiles, mBuccaneers)
                Fight = mScript
            End If
        End If

    Else 'hostiles are all dead
        Fight = "Hostiles are all dead. Generate a new set of hostiles"
    End If

Else
    Fight = "Buccaneers are all dead :(. Suggest building or loading a new buccaneer group"
End If
End Function

这就是你需要做的一切,就像一个魅力

答案 4 :(得分:0)

在COM中,对象实例的类型和对象变量的类型之间存在差异。特别是,对象变量的类型表现为接口类型。每种类型至少实现一个接口(本身),但类型也可以实现其他接口。这种能力被用来伪造继承。

在某些框架中,如果类Foo具有私有成员Bar,则任何类型为Foo的非null变量将保存对包含该成员的某个类对象的引用。该成员可能无法访问任何外部代码,但它将存在,因此可以从Foo的代码中的任何位置进行访问。

因为COM类变量类型的行为类似于接口而不是可继承的类类型,所以不能保证类型Foo的变量将引用具有任何Foo非的对象。 - 公共成员。虽然编译器可以知道Me将始终引用当前对象(实际类型为Foo),但Foo的私有成员所在的唯一对象可能是access Me意味着编译器没有真正的理由支持私有成员的基于点的解除引用。