2

我一直在尝试在 VBA 中实现一个非常简单的树结构来满足一些基本的文本解析需求。相关代码如下。

Private pLeaves() As CTree
Private numLeaves As Integer
Private leavesLen As Integer
Private iterate As Integer
Private pParent As CTree
Public pValue As Object

Public Sub class_initialize()
    ReDim pLeaves(10)
    leavesLen = 10
    numLeaves = 0
    Set pParent = Nothing
    iterate = 0
    Set pValue = Nothing

End Sub
Public Sub Class_terminate()
    'We'll leave it empty for now
    'if it looks like it's not working right we might change it
End Sub

Public Property Get Parent() As CTree
    Parent = pParent
End Property

Public Property Get Leaves() As CTree
    Leaves = pLeaves
End Property
Private Property Set Parent(ByRef p As CTree)
    Set pParent = p
End Property

Private Property Set value(ByRef value As Object)
    Set pValue = value
End Property


Public Sub Add_Leaf(ByRef value As Object)
    Dim n As Integer
    n = numLeaves
    If numLeaves >= leavesLen Then
       ReDim Preserve pLeaves(leavesLen + 10)
       leavesLen = leavesLen + 10
    End If
   Set pLeaves(n) = New CTree
   Set pLeaves(n).Parent = Me
   Set pLeaves(n).value = value
End Sub

Public Function DFFind_Leaf(value As Object) As CTree
    Dim i As Integer

    If pValue = value Then
        Set DFFind_Leaf = Me
        Return
    End If

    If numLeaves = 0 Then
        Set DFFind_Leaf = Nothing
        Return
    End If


    For i = 0 To numLeaves
        Set DFFind_Leaf = pLeaves(i).DFFind_Leaf(value)
        If DFFind_Leaf <> Nothing Then
            Return
        End If
    Next i

    Set DFFind_Leaf = Nothing
    Return
End Function

当我尝试使用对象调用 Add_Leaf 函数时,尽管我最终 在我尝试的行上从 VBA获得了方法或数据成员未找到错误

set pLeaves(n).Parent= me

知道这可能是什么原因吗?

编辑:好的,我想出了如何解决这个问题。将 set 属性 Parent(...) 从 private 更改为 public 解决了这个问题。所以显然我不太明白 private 在 vba 中究竟做了什么。如果有人想解释如何做到这一点,而基本上不暴露任何人想要设置的变量,我将不胜感激。

4

1 回答 1

2

Private告诉 VBA 解释器变量的范围仅限于类/模块。因此,您只能在原始类内部访问它,而不能从外部访问它。Public另一方面,允许您从外部访问变量。

但是,请注意,在使用类时,强烈建议不要公开公开任何变量。SET PROPERTY相反,最好的做法是使用andGET PROPERTY关键字公开所谓的属性。

即代替

Public Amount as Double

使用这种方法通常会更好:

Private mAmount as Double
Property Set Amount(amt as Double) 'Note that by default, properties are public
    If amt > 0 Then
        mAmount = amt
    Else
        mAmount = 0
    End If
End Property

Property Get Amount as Double
    Amount = mAmount
End Property

正如您从这个示例中看到的那样,优点是您实际上可以添加额外的验证/修改,从而确保一致性。

在您的示例中,您可以考虑简单地提供一个方法,即一个公共子程序,它添加一个休假并处理所有设置,例如

Public Sub AddLeave(strName as String)
    Dim objLeave as New CTree
    objLeave.Init strName, Me
    mLeaves.Add objLeave, strName
End Sub

Public Sub Init(strName as String, objParent as CTree)
    Me.Name = strName
    Set Me.Parent = objParent
End Sub
于 2013-03-05T11:12:23.687 回答