将字典放入课堂 [英] Putting dictionaries into classes

查看:88
本文介绍了将字典放入课堂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几个星期前,我得到了一个关于如何在此位置制作通用类模块的神话般的答案:

A few weeks ago, I was given a fabulous answer on how to make a general class module at this location: Class "let" stuck in infinite loop

说实话,我仍然不了解太多,因为我的vba知识100%是自学的,从这里开始,几年前C的一个学期还剩下一些通用编程逻辑.但是我认为我对此很有把握,因为这是一个很好的解释.我现在正在尝试将此方法与类中的字典一起使用,并且遇到了一些麻烦.

I still don't know that much, to be honest, since 100% of my vba knowledge is self-taught and from here, with a smattering of general programming logic leftover from a semester of C several years ago. But I thought I had a good grasp on that, because it was a good explanation. I'm now trying to apply this to use with dictionaries inside of my classes and running into some trouble.

我的课程模块如下:

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在立即窗口中对此进行测试.那没有用.然后,我将Initialize修改为:

I then tried to test this in the immediate window with set tester = new WeatherData (the name of the module) and Initialize. That did not work. I then modified Initialize to be:

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,但这也不起作用(编译错误:未定义子函数或函数").

and entered Initialize tester, but this did not work either ("Compile Error: Sub or Function not defined").

所以,最后一个问题是:如何将三个词典放入类模块中?

So, end question: how do I go about putting three dictionaries in a class module?

我是个傻瓜.以下代码本身并不能真正解决问题,但至少可以绕过它,直到我不必承认这一点:

I am a fool. The following doesn't really solve the problem per se, but it did at least skirt around it to the point that I don't have to acknowledge it:

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; dr:创建数组而不是字典,并完全删除初始化.您的键"别无选择,只能是数字,但至少有效.如果有人愿意,我真的很想知道一个实际的解决方案,但是我遇到的具体问题已经解决了.

tl;dr: make arrays instead of dictionaries, and cut out initialize entirely. Your "keys" have no choice but to be numbers, but it works, at least. I would be really interested in knowing an actual solve, if anyone is so inclined, but the specific issue I had is solved.

推荐答案

似乎要实现索引属性.

简化到最低限度:

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属性,这需要索引(/键)作为参数.

You keep the dictionaries safely encapsulated as an implementation detail of your class (external code cannot set them to Nothing, for example), and expose an indexed Get+Let property for each encapsulated dictionary, that takes the index (/key) as a parameter.

对于您的WeatherData类,这意味着您可以像这样填充数据:

In the case of your WeatherData class, this means you can populate the data like this:

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

然后使用data.Temp("day 1")检索"day 1"的温度.

对于您的初始化方法,需要从该类的实例调用它-这是一个 instance方法.

As for your initializer method, it needed to be called from an instance of the class - being an instance method.

因此,您应该完成tester.Initialize而不是Initialize tester.

So instead of Initialize tester you should have done tester.Initialize.

无论内部封装存储是数组,CollectionDictionary都与调用代码没有区别-这是一个封装的实现细节:您的类也可以将数据存储在.csv文件中,也可以存储在.csv文件中.如果需要的话,将其导入数据库.

Whether you make the internal encapsulated storage an array, a Collection or a Dictionary makes no difference to the calling code - it's an encapsulated implementation detail: your class could just as well store the data in .csv files or into a database if it wanted.

这篇关于将字典放入课堂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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