2017-04-06 82 views
2

几个星期前,我就如何在这个位置做一个普通类模块神话般答案:Class "let" stuck in infinite loop把词典分成类

我仍然不知道那么多,说实话,因为我的vba知识中有100%是自学成才的,从这里开始,几年前C学期剩下的一般编程逻辑就是一小部分。但我认为我对此有了很好的把握,因为这是一个很好的解释。我现在试图将其应用于我的课堂内的字典并遇到一些麻烦。

我的类模块如下:

Option Explicit 

Private Type categories 
    Temp As scripting.Dictionary 
    Humid As scripting.Dictionary 
    Wind As scripting.Dictionary 
End Type 

Private this As categories 

Public Sub Initialize() 
    Set this.Temp = New scripting.Dictionary 
    Set this.Humid = New scripting.Dictionary 
    Set this.Wind = New scripting.Dictionary 
End Sub 

Public Property Get Temp(ByVal HourIndex As Long) As Double 
    Temp = this.Temp(HourIndex) 
End Property 

Public Property Let Temp(ByVal HourIndex As Long, ByVal Value As Double) 
    this.Temp(HourIndex) = Value 
End Property 

Public Property Get Humid(ByVal HourIndex As Long) As Double 
    Humid = this.Humid(HourIndex) 
End Property 

Public Property Let Humid(ByVal HourIndex As Long, ByVal Value As Double) 
    this.Humid(HourIndex) = Value 
End Property 

Public Property Get Wind(ByVal HourIndex As Long) As Double 
    Wind = this.Wind(HourIndex) 
End Property 

Public Property Let Wind(ByVal HourIndex As Long, ByVal Value As Double) 
    this.Wind(HourIndex) = Value 
End Property 

然后我试着用set tester = new WeatherData(模块的名称)和Initialize测试这在即时窗口。这没有用。然后我修改初始化为:

Public Sub Initialize(ByVal variable As categories) 
    Set variable.Temp = New scripting.Dictionary 
    Set variable.Humid = New scripting.Dictionary 
    Set variable.Wind = New scripting.Dictionary 
End Sub 

,进入Initialize tester,但这并没有工作,要么(“编译错误:子或未定义功能”)。

因此,最终的问题:我该如何着手将三个字典放在类模块中?

编辑:我是个傻瓜。下面并没有真正解决问题本身,但它确实至少裙摆周围到我没有承认这一点:

Option Explicit 

Private Type categories 
    Temp(23) As Double 
    Humid(23) As Double 
    wind(23) As Double 
End Type 

Private this As categories 

Public Property Get Temp(ByVal HourIndex As Long) As Double 
    Temp = this.Temp(HourIndex) 
End Property 

Public Property Let Temp(ByVal HourIndex As Long, ByVal Value As Double) 
    this.Temp(HourIndex) = Value 
End Property 

Public Property Get Humid(ByVal HourIndex As Long) As Double 
    Humid = this.Humid(HourIndex) 
End Property 

Public Property Let Humid(ByVal HourIndex As Long, ByVal Value As Double) 
    this.Humid(HourIndex) = Value 
End Property 

Public Property Get wind(ByVal HourIndex As Long) As Double 
    wind = this.WindChill(HourIndex) 
End Property 

Public Property Let wind(ByVal HourIndex As Long, ByVal Value As Double) 
    this.wind(HourIndex) = Value 
End Property 

TL;博士:让数组来代替字典,并完全初始化。你的“钥匙”别无选择,只能算数字,但至少可以工作。如果任何人都如此倾向,我会真正有兴趣知道一个实际的解决方案,但我解决的具体问题已经解决。

+1

“它不起作用”并不完全是一个明确的问题陈述,但是Temp,Humid和Wind都暴露为Double,你不能将它们分配给Dictionary '参考... –

+0

我这样做是因为它将成为双打字典,尽管我不知道它是否会让我得到任何地方。那么这会作为一个数组工作吗?我编辑补充说,返回的错误是关于'Initialize'的编译错误。 –

+0

'Initialize'方法是'WeatherData'的成员? –

回答

1

似乎你想实施一个索引性质

简化到最低限度:

Option Explicit 
Private values As Scripting.Dictionary 

Private Sub Class_Initialize() 
    Set values = New Scripting.Dictionary 
End Sub 

Public Property Get Something(ByVal key As String) As Double 
    Something = values(key) 
End Property 

Public Property Let Something(ByVal key As String, ByVal value As Double) 
    values(key) = value 
End Property 

你保持安全的封装为您的类的实现细节的字典(外部代码不能将它们设置为Nothing,例如),并揭露一个索引Get + Let每个封装字典的属性,它将索引(/ key)作为参数。

在你WeatherData类的情况下,这意味着你可以填充像这样的数据:

Set data = New WeatherData 
With data 
    .Temp("day 1") = 76 
    .Temp("day 2") = 78 
    .Humid("day 1") = 0.55 
    .Humid("day 2") = 0.61 
    .Wind("day 1") = 0.92 
    .Wind("day 2") = 1.27 
End With 

,然后检索的"day 1"温度与data.Temp("day 1")

至于你的初始化方法,它需要从一个类的实例称为 - 作为一个实例方法

因此,而不是Initialize tester你应该做了tester.Initialize

无论你使内部封装的存储阵列,CollectionDictionary使得调用代码没有区别 - 这是一个封装的实现细节:类可能只是以及存储为.csv文件或到一个数据库中的数据如果它想要的话。

+0

我有这个工作了一会儿,我兴奋起来,但后来停止了。我把你的代码放在你的代码中,然后在直接窗口中,我设置了tester = new weatherdata,然后是'debug.print tester.values.count',我得到一个消息,说明该对象不支持该属性/方法。 –

+0

'values'是'Private',你不能从外部访问它(它是整个点!) - 如果你的外部代码需要知道有多少值,那么你需要暴露'TempItemCount','' HumidItemCount'和'WindItemCount'属性返回相应内部集合的'.Count'。 –

+0

好吧,所以我想我错过的是我引用类中的函数,而不是字典对象?我不需要访问'.count',我只是将它用作测试设备来查看代码是否工作。但是,不是'debug.print tester.values',而是适当的形式是'tester.something(key)'?如果我想要放入多个字典,我会同时声明'values'和'values2',然后将'something2'与'something2'完全一样,除了作用于'values2'? –

0

在这种情况下,你应该按如下方式使用后期绑定:

Private Type categories 
    Temp As Object 
    Humid As Object 
    Wind As Object 
End Type 

Private this As categories 

Public Sub Initialize() 
    Set this.Temp = CreateObject("Scripting.Dictionary") 
    Set this.Humid = CreateObject("Scripting.Dictionary") 
    Set this.Wind = CreateObject("Scripting.Dictionary") 
End Sub 

而且你不能使用多个参数用Let。你应该用一个函数来做到这一点:

Public Function SetTemp(ByVal HourIndex As Long, ByVal Value As Double) 
    this.Temp(HourIndex) = Value 
End Function 

要运行这个我用:

Sub test() 
    Dim multi As Dictionaries 
    Set multi = New Dictionaries 

    multi.Initialize 

    multi.SetTemp 13, 25.522 
    Debug.Print multi.Temp(13) 
End Sub 

凡我类模块被命名为Dictionaries。所以基本上使用后期绑定,并将所有多参数让函数改为简单函数。

+0

只要参考值已设定,他就没有理由迟到。有机会,但参考只是设置不正确。 –