使用子级别创建类属性 [英] Creating Class properties with sub levels

查看:69
本文介绍了使用子级别创建类属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读



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



我读过的主题只有很少的示例,因此无法解决。我假设使用collections可以实现这一点,但我不确定如何查找。



我的数据来自2个表,其中一个包含所有项目但是部门和另一部门的ID随部门而异。这两个表都有当前月份的日期作为标题,并且它们的时间表/部门取决于该表。



我想知道如何实现这一天,但是没有整个月。



这是我为课堂编写的基础知识:

  Option Explicit 
私有DirNeg作为字符串
私有Agrup作为字符串
私有DNI作为字符串
私有Centro作为字符串
私有Servicio作为字符串
私有Nombre作为字符串
属性Get Business()作为字符串
商业= DirNeg
最终财产
属性Let Business(ByVal sBusiness作为字符串)
DirNeg = sBusiness
结束属性
属性获取Group()作为字符串
组= Agrup
结束属性
属性Let Group(ByVal sGroup作为字符串)
Agrup = sGroup
结束属性
属性获取ID()作为字符串
ID = DNI
结束属性
属性Let ID(ByVal sID作为字符串)
DNI = sID
最终财产
财产Location()As String
Location = Centro
End Property
Property Let Location(ByVal sLocation As String)
Centro = sLocation
End Property
Property Get Service()作为字符串
服务= Servicio
结束属性
属性让Service(ByVal sService作为字符串)
Servicio = sService
结束属性
属性Get Name()作为字符串
名称= Nombre
结束属性
属性让Name(ByVal sName作为字符串)
Nombre = sName
结束属性

另一方面,在 Class_Initialize

EDIT / UPDATE:



这是我的数据的样子:



安排座席信息旁边的时间表





部门与代理商ID一起





clAgent类模块:

 选项显式
私有DirNeg作为字符串
私有Agrup作为字符串
私有DNI作为字符串
私有Centro作为字符串
私有服务作为字符串
私有Nombre作为字符串
私有Fechas作为对象
属性y 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
物业获取Location()作为字符串
位置= Centro
结束物业
物业让Location(ByVal sLocation作为字符串)
物业= sLocation
结束物业
属性Get Service()作为字符串
服务= Servicio
结束属性
属性让Service(ByVal sService作为字符串)
Servicio = sService
结束属性
Property Get Name()As String
Name = Nombre
End Property
Property Let Name(ByVal sName As String)
Nombre = sName
最终属性
属性获取clFechas(ByVal StringKey作为字符串)作为clFechas
与Fechas
如果不是.Exists(StringKey)然后
Dim objFechas作为新clFechas
。添加StringKey,objFechas

结尾的结束

结尾的属性
私有子类Class_Initialize()

设置Fechas = CreateObject ( Scripting.Dictionary)

结束子

clFechas类模块:

 选项显式
私有Modos作为对象
私有Horarios作为对象
'Proposedad Moda para clase Fecha
公共属性获取Modo(ByVal StringKey作为字符串)As String
Modo = Modos(StringKey)
最终属性
公共属性让Modo(ByVal StringKey作为字符串,ByVal StringValue作为字符串)
Modos(StringKey)= StringValue
最终属性
公共属性Get Keys()作为变量
Keys = Modos。按键
End Pr操作
'Proposedad Horario para clase Fecha
公共财产获取Horario(ByVal StringKey作为字符串)As String
Modo = Horarios(StringKey)
最终财产
公共属性让Horarios(ByVal StringKey作为字符串,ByVal StringValue作为字符串)
Horarios(StringKey)= StringValue
终端属性
公共属性Get Keys()作为变量
Keys = Horarios.Keys
最终属性
'Iniciamos la clase
Private Sub Class_Initialize()
Set Modos = CreateObject( Scripting.Dictionary)
Set Horarios = CreateObject( Scripting.Dictionary)
结束子
私有子类Class_Terminate()
设置Modos =否
设置Horarios =没什么
结束Sub


解决方案

您似乎对常规属性没有任何疑问,所以让我们关注一下复杂的那些;时间表和部门。



属性基本上是列表,日期是索引,项目是对象。

我个人更喜欢使用字典,因为我可以查看键是否存在等。



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






 选项显式
私有m_schedules作为对象

公共属性获取日程表(ByVal键作为日期)如附表
和m_schedules
如果不存在.Exists(Key)然后.Add键,新附表

结尾设置时间表= m_schedules(Key)
最终属性

'出于测试目的-可以省略。
公共属性Get Keys()as Variant
Keys = m_schedules.Keys
End Property

’出于测试目的-可以省略。
公共属性Get Count()只要
Count = m_schedules.Count
最终属性

Private Sub Class_Initialize()
Set m_schedules = CreateObject( Scripting.Dictionary)
结束子

私有子类Class_Terminate()
Set m_schedules = Nothing
结束子

时间表类:






  Option显式
私有m_schedule作为字符串

公共属性获取Schedule()作为字符串
Schedule = m_schedule
结束属性
公共Property Let Schedule(ByVal param as String)
m_schedule = param
End Property

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






  Sub Test()

Dim obj作为代理
设置obj =新代理

obj.Schedule(#1/9/2019#)。Schedule =计划1
obj。 Schedule(#2/9/2019#)。Schedule = Schedule 2
obj.Schedule(#3/9/2019#)。Schedule = Schedule 3

PrintToDebug obj

'让我们进行更改
obj.Schedule(#2/9/2019#)。Schedule = Schedule 2222

PrintToDebug obj

结束子


Private Sub PrintToDebug(ByVal obj作为代理)

Debug.Print

变体
和obj
为每个m In。键
Debug.Print键:&并购字符串(3,)& 值:& .Schedule(m).Schedule
接下来的m


结尾Debug.Print Total Items:& obj.Count
结束子

输出:

 '键:09/01/2019值:附表1 
'键:09/02/2019值:附表2
'键:09 / 03/2019价值:附表3
'总商品:3

'钥匙:09/01/2019价值:附表1
'钥匙:2019年9月2日价值:Schedule 2222
'Key:09/03/2019 Value:Schedule 3
'Total Items:3

有关词典对象的其他信息,可以在这里找到:字典对象



心神。这很重要:


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


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


I've been reading this topic on how to use class modules.

My goal is to improve my code performance and readability so I think I'm in the right path.

But I have some questions about the limitations.

In my head i want to do this:

Is it possible to achieve such a structure?

The topic I've read has very few examples and this is not handled. I'm assuming this would be possible with collections of collections, but I not sure how to look for this.

My data comes from 2 tables, one has all the items but the department and the other one has the ID's alongisde the departments. Both tables have the dates of the current month as headers and their Schedule/Department depending on the table.

I'd know how to achieve this for one day, but not for a whole month.

This is how I wrote the basics for my class:

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

On the other hand, is it correct to fill the whole class on the Class_Initializeevent? My data will always be the same so I don't need to loop in a normal module to fill the class, it could be done everytime the class is created.

EDIT/UPDATE:

This is how my data looks like:

Schedules alongside Agent's info

Departments alongside Agent's ID

clAgent Class Module:

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 Class Module:

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

解决方案

You don’t seem to have any issues with regular properties so let’s focus on the complex ones; Schedule and Department. Both are the same, so same rules apply to both.

The property is basically list, the date is the index and the item is an object. I personally prefer to work with dictionaries as I can look if a key exist etc.

So, your Agent class could look something like this:


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

The Schedules class:


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

Now, let's test it:


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

Output:

'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

Additional information regarding the Dictionary object can be found here: Dictionary object

Also keep this in mind. It's quite important:

If key is not found when changing an item, a new key is created with the specified newitem. If key is not found when attempting to return an existing item, a new key is created and its corresponding item is left empty.

If the dictionary item is not a simple string, let me know to update the answer. Sorry, I couldnt read the data in the screenshots. :)

这篇关于使用子级别创建类属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆