VBA类模块:使用另一个属性从对象获取属性

时间:2017-10-25 14:34:11

标签: excel vba class object

全部, 我在VBA中设置一个类模块结构来添加具有多个里程碑的计划,但我对它很新。我做了以下事情:

  • 一个名为“Plan”的类模块,其中包含“name”属性(字符串)和“里程碑”属性(类里程碑)。
  • 此里程碑类模块是名为“里程碑”的类模块的对象集合。
  • “里程碑”类具有“名称”属性和“值”属性。

所以在我的模块中,我现在指定特定计划的里程碑:

Plan.Milestones.Add "MilestoneA", Cells(i, 5)
Plan.Milestones.Add "MilestoneB", Cells(i, 7)
...

到现在为止一切都很好。现在对于MilestoneC,我想知道MilestoneA的价值。如何获取名为“MilestoneA”的里程碑的值。

我知道下面的代码会给我答案,但我不想硬编码'item(1)'(我想用名字):

Plan.Milestones.Item(1).Value

在clsMilestones类中:

Private prvt_Milestones As New Collection

Property Get Item(Index As Variant) As clsMilestone
    Set Item = prvt_Milestones(Index)
End Property

Sub Add(param_Name As String, param_Value As String)

    Dim new_milestone As clsMilestone
    Set new_milestone = New clsMilestone

    new_milestone.Name = param_Name
    new_milestone.Value = param_Value

    prvt_Milestones.Add new_milestone
End Sub

3 个答案:

答案 0 :(得分:3)

您的Milestones课程是集合课程。按照惯例,集合类具有Item属性,即类默认成员

,您无法在VBA中轻松指定类的默认成员

导出代码文件,在记事本中打开它。找到您的Public Property Get Item成员并添加VB_UserMemId属性 - 当您在那里时,您也可以添加VB_Description属性:

Public Property Get Item(ByVal Index As Variant) As Milestone
Attribute Item.VB_UserMemId = 0
Attribute Item.VB_Description = "Gets the item at the specified index, or with the specified name."
    Set Item = prvt_Milestones(Index)
End Property

UserMemId = 0是使该属性成为类'默认成员的原因 - 请注意,该类中只有一个成员可以拥有该值。

暂时不要保存和关闭。

您也希望自己的集合类也可以使用For Each循环,为此,您需要一个返回NewEnum的{​​{1}}属性,属性和标志的数量:

IUnknown

请注意,您的内部封装Public Property Get NewEnum() As IUnknown Attribute NewEnum.VB_Description = "Gets an enumerator that iterates through the collection." Attribute NewEnum.VB_UserMemId = -4 Attribute NewEnum.VB_MemberFlags = "40" Set NewEnum = prvt_Milestones.[_NewEnum] End Property 有一个隐藏成员,其名称以下划线开头 - 这在VBA中是非​​法的,因此要调用它,您需要用方括号括起来。

现在这段代码是合法的:

Collection

保存文件,关闭文件,然后将其重新导入项目中。

由于您使用字符串键填充集合(至少这是您的Dim ms As Milestone For Each ms In Plan.Milestones Debug.Print ms.Name, ms.Value ', ms.DateDue, ... Next 方法似乎正在执行的操作),因此客户端代码可以使用索引或键来检索项目。 / p>

现在Add是类默认成员,现在这是合法的:

Item

请注意,添加到内部集合时,Set milestoneA = Plan.Milestones("Milestone A").Value 方法需要为Add参数指定值 - 如果您希望按Key键入项,请使用{{1作为关键:

Name

答案 1 :(得分:2)

dictionary中使用Milestoneplan class个班级,并将key设置为" Milestone_x"并且itemmilestone class

然后你可以说Plan.Milestones("Milestone99")

答案 2 :(得分:0)

将属性添加到里程碑类,该类根据名称返回里程碑:

Property Get SelectByName(strMilestoneName as string) as clsMilestone
     Dim vIndex
     'Add code here to find the index of the milestone in question
     vIndex = ????????

     Set SelectByName = prvt_Milestones(Index)
End Property

OR

编辑项目属性以允许通过索引或名称进行选择:

Property Get Item(Index As Variant) As clsMilestone
    If isNumeric(Index) then
       Set Item = prvt_Milestones(Index)
    Else
       'Find Item based on Name
        Dim vIndex
        vIndex = ?????
       Set Item = prvt_Milestones(vIndex)
     End If
End Property