使用子级别创建类属性

时间:2019-09-04 09:59:59

标签: excel vba class

我一直在阅读topic,了解如何使用类模块。

我的目标是提高代码性能和可读性,因此我认为自己是对的。

但是我对限制有一些疑问。

我想这样做:

enter image description here

是否可以实现这样的结构?

我读过的主题只有很少的示例,因此无法解决。我以为使用收藏集可以做到这一点,但是我不确定如何查找。

我的数据来自2个表,一个表具有所有项目,但部门除外,另一个表具有ID沿部门分布。这两个表都将当月的日期作为标题,并且它们的时间表/部门取决于表。

我会在一天内而不是整个一个月内实现这一目标。

这是我编写班级基础知识的方式:

Option Explicit
Private DirNeg As String
Private Agrup As String
Private DNI As String
Private Centro As String
Private Servicio As String
Private Nombre As String
Property Get Business() As String
    Business = DirNeg
End Property
Property Let Business(ByVal sBusiness As String)
    DirNeg = sBusiness
End Property
Property Get Group() As String
    Group = Agrup
End Property
Property Let Group(ByVal sGroup As String)
    Agrup = sGroup
End Property
Property Get ID() As String
    ID = DNI
End Property
Property Let ID(ByVal sID As String)
    DNI = sID
End Property
Property Get Location() As String
    Location = Centro
End Property
Property Let Location(ByVal sLocation As String)
    Centro = sLocation
End Property
Property Get Service() As String
    Service = Servicio
End Property
Property Let Service(ByVal sService As String)
    Servicio = sService
End Property
Property Get Name() As String
    Name = Nombre
End Property
Property Let Name(ByVal sName As String)
    Nombre = sName
End Property

另一方面,在Class_Initialize事件中填充整个班级是否正确?我的数据总是一样的,所以我不需要循环一个普通的模块来填充类,可以在每次创建类时完成。

编辑/更新:

这是我的数据的样子:

安排代理人的信息

enter image description here

部门与探员的ID一起

enter image description here

clAgent类模块:

Option Explicit
Private DirNeg As String
Private Agrup As String
Private DNI As String
Private Centro As String
Private Servicio As String
Private Nombre As String
Private Fechas As Object
Property Get Business() As String
    Business = DirNeg
End Property
Property Let Business(ByVal sBusiness As String)
    DirNeg = sBusiness
End Property
Property Get Group() As String
    Group = Agrup
End Property
Property Let Group(ByVal sGroup As String)
    Agrup = sGroup
End Property
Property Get ID() As String
    ID = DNI
End Property
Property Let ID(ByVal sID As String)
    DNI = sID
End Property
Property Get Location() As String
    Location = Centro
End Property
Property Let Location(ByVal sLocation As String)
    Centro = sLocation
End Property
Property Get Service() As String
    Service = Servicio
End Property
Property Let Service(ByVal sService As String)
    Servicio = sService
End Property
Property Get Name() As String
    Name = Nombre
End Property
Property Let Name(ByVal sName As String)
    Nombre = sName
End Property
Property Get clFechas(ByVal StringKey As String) As clFechas
    With Fechas
        If Not .Exists(StringKey) Then
            Dim objFechas As New clFechas
            .Add StringKey, objFechas
        End If
    End With

End Property
Private Sub Class_Initialize()

    Set Fechas = CreateObject("Scripting.Dictionary")

End Sub

clFechas类模块:

Option Explicit
Private Modos As Object
Private Horarios As Object
'Aqiço creamos la propiedad Modo para la clase Fecha
Public Property Get Modo(ByVal StringKey As String) As String
    Modo = Modos(StringKey)
End Property
Public Property Let Modo(ByVal StringKey As String, ByVal StringValue As String)
    Modos(StringKey) = StringValue
End Property
Public Property Get Keys() As Variant
    Keys = Modos.Keys
End Property
'Aquí creamos la propiedad Horario para la clase Fecha
Public Property Get Horario(ByVal StringKey As String) As String
    Modo = Horarios(StringKey)
End Property
Public Property Let Horario(ByVal StringKey As String, ByVal StringValue As String)
    Horarios(StringKey) = StringValue
End Property
Public Property Get Keys() As Variant
    Keys = Horarios.Keys
End Property
'Iniciamos la clase
Private Sub Class_Initialize()
    Set Modos = CreateObject("Scripting.Dictionary")
    Set Horarios = CreateObject("Scripting.Dictionary")
End Sub
Private Sub Class_Terminate()
    Set Modos = Nothing
    Set Horarios = Nothing
End Sub

1 个答案:

答案 0 :(得分:2)

您似乎对常规属性没有任何问题,因此让我们集中讨论复杂属性;时间表和部门。两者是相同的,因此相同的规则适用于两者。

该属性基本上是列表,日期是索引,项目是对象。我个人更喜欢使用字典,因为我可以查看是否存在键等。

因此,您的Agent类可能看起来像这样:


Option Explicit
Private m_schedules As Object

Public Property Get Schedule(ByVal Key As Date) As Schedules
    With m_schedules
        If Not .Exists(Key) Then .Add Key, New Schedules
    End With
    Set Schedule = m_schedules(Key)
End Property

'For testing purposes - can be ommited.
Public Property Get Keys() As Variant
    Keys = m_schedules.Keys
End Property

'For testing purposes - can be ommited.
Public Property Get Count() As Long
    Count = m_schedules.Count
End Property

Private Sub Class_Initialize()
    Set m_schedules = CreateObject("Scripting.Dictionary")
End Sub

Private Sub Class_Terminate()
    Set m_schedules = Nothing
End Sub

时间表类:


Option Explicit
Private m_schedule As String

Public Property Get Schedule() As String
    Schedule = m_schedule
End Property
Public Property Let Schedule(ByVal param As String)
    m_schedule = param
End Property

现在,让我们对其进行测试:


Sub Test()

    Dim obj As Agent
    Set obj = New Agent

    obj.Schedule(#1/9/2019#).Schedule = "Schedule 1"
    obj.Schedule(#2/9/2019#).Schedule = "Schedule 2"
    obj.Schedule(#3/9/2019#).Schedule = "Schedule 3"

    PrintToDebug obj

    'Lets make a change
    obj.Schedule(#2/9/2019#).Schedule = "Schedule 2222"

    PrintToDebug obj

End Sub


Private Sub PrintToDebug(ByVal obj As Agent)

    Debug.Print ""

    Dim m As Variant
    With obj
        For Each m In .Keys
            Debug.Print "Key: " & m & String(3, " ") & "Value: " & .Schedule(m).Schedule
        Next m
    End With

    Debug.Print "Total Items: " & obj.Count
End Sub

输出:

'Key: 09/01/2019   Value: Schedule 1
'Key: 09/02/2019   Value: Schedule 2
'Key: 09/03/2019   Value: Schedule 3
'Total Items: 3

'Key: 09/01/2019   Value: Schedule 1
'Key: 09/02/2019   Value: Schedule 2222
'Key: 09/03/2019   Value: Schedule 3
'Total Items: 3

有关Dictionary对象的其他信息可以在这里找到:Dictionary object

也请记住这一点。这很重要:

  

如果在更改项目时未找到密钥,则使用   指定的newitem。如果尝试返回时找不到密钥   现有项目,将创建一个新密钥,其对应项目为   留空。

如果词典项不是简单的字符串,请告诉我以更新答案。抱歉,我无法读取屏幕截图中的数据。 :)