我需要数组,类,字典或集合吗?

时间:2015-07-02 16:31:30

标签: excel excel-vba vba

我不确定我正在尝试做什么是最好的选择。目前,我正在使用3D数组来保存这些值,但我现在正在学习VBA中的词典,类和集合,并且无法确定这些对于我正在尝试的内容是否更好或更有用要做。

我每个月都会得到一个新的数据电子表格,我需要遍历查找数字的单元格,并根据该数字替换另一个单元格的数据。 I.E. (全部在A组)

4323
4233
4123
4343
4356
3213

在B栏中,我需要放一个相应的国家。如果前两位是43,则右边的单元格应为“德国”,然后是col。 C,“DEU”。如果两个数字是41,那么col。 B细胞应为“USA”,C为“USA”等。等

目前,我正在设置一个3D数组(伪代码):

myArray(0,0) = 43
myArray(0,1) = "Germany"
myArray(0,2) = "DEU"
myArray(1,0) = 41
myArray(1,1) = "United States"
myArray(1,2) = "USA" 
etc. etc.

然后,我有一个循环遍历所有单元格并替换信息。

一个班级或许会更好吗?然后,我可以做一些像创建一个cntry。 Code,cntry.Country,cntry.CountryAbbrev并使用它们来引用“43”,“德国”和“DEU”

(再次,伪代码):

num = left("A1",2) 
'then here, somehow find the num in cntry.Code list - will need to work out how
Cells("B1").Value = cntry.Country
Cells("C1").Value = cntry.CountryAbbrev

... 至于字典,我认为这是行不通的,因为(AFAIK)每个条目只能有一个密钥。所以我可以做国家号码(“43”),但只设置国家名称或国家缩写 - 但不是两个....正确吗?

这个问题有意义吗?在类似的东西上使用类/字典矫枉过正吗?收藏是最好的吗?

感谢您的任何建议/指导!

2 个答案:

答案 0 :(得分:2)

课程模块就是答案。它始终是答案。代码是代码,您在类模块中几乎无法做任何事情,您无法在标准模块中执行此操作。类只是以不同方式组织代码的一种方式。

但接下来的问题是如何将数据存储在类模块中。我习惯使用Collections,但Collection或Scripting.Dictionary是你最好的选择。

我创建一个名为CCountry的类,看起来像这样

Private mlCountryID As Long
Private msCode As String
Private msFullname As String
Private msAbbreviation As String

Public Property Let CountryID(ByVal lCountryID As Long): mlCountryID = lCountryID: End Property
Public Property Get CountryID() As Long: CountryID = mlCountryID: End Property
Public Property Let Code(ByVal sCode As String): msCode = sCode: End Property
Public Property Get Code() As String: Code = msCode: End Property
Public Property Let Fullname(ByVal sFullname As String): msFullname = sFullname: End Property
Public Property Get Fullname() As String: Fullname = msFullname: End Property
Public Property Let Abbreviation(ByVal sAbbreviation As String): msAbbreviation = sAbbreviation: End Property
Public Property Get Abbreviation() As String: Abbreviation = msAbbreviation: End Property

然后我创建了一个名为CCountries的类来保存我所有的CCountry实例

Private mcolCountries As Collection

Private Sub Class_Initialize()
    Set mcolCountries = New Collection
End Sub

Private Sub Class_Terminate()
    Set mcolCountries = Nothing
End Sub

Public Property Get NewEnum() As IUnknown
    Set NewEnum = mcolCountries.[_NewEnum]
End Property

Public Sub Add(clsCountry As CCountry)
    If clsCountry.CountryID = 0 Then
        clsCountry.CountryID = Me.Count + 1
    End If

    mcolCountries.Add clsCountry, CStr(clsCountry.CountryID)
End Sub

Public Property Get Country(vItem As Variant) As CCountry
    Set Country = mcolCountries.Item(vItem)
End Property

Public Property Get Count() As Long
    Count = mcolCountries.Count
End Property

你看到CCountries在这一点上只是一个集合。您可以在http://dailydoseofexcel.com/archives/2010/07/09/creating-a-parent-class/

了解有关该NewEnum属性的更多信息

然后我将所有国家的东西放在一张桌子里,然后把那张桌子读进我的班级。在CCountries

Public Sub FillFromRange(rRng As Range)

    Dim vaValues As Variant
    Dim i As Long
    Dim clsCountry As CCountry

    vaValues = rRng.Value

    For i = LBound(vaValues, 1) To UBound(vaValues, 1)
        Set clsCountry = New CCountry
        With clsCountry
            .Code = vaValues(i, 1)
            .Fullname = vaValues(i, 2)
            .Abbreviation = vaValues(i, 3)
        End With
        Me.Add clsCountry
    Next i

End Sub

我需要一种通过其中一个属性找到国家的方法

Public Property Get CountryBy(ByVal sProperty As String, ByVal vValue As Variant) As CCountry

    Dim clsReturn As CCountry
    Dim clsCountry As CCountry

    For Each clsCountry In Me
        If CallByName(clsCountry, sProperty, VbGet) = vValue Then
            Set clsReturn = clsCountry
            Exit For
        End If
    Next clsCountry

    Set CountryBy = clsReturn

End Property

然后我按下我的数字列表并将代码放在他们旁边

Sub FillCodes()

    Dim clsCountries As CCountries
    Dim rCell As Range
    Dim clsCountry As CCountry

    Set clsCountries = New CCountries
    clsCountries.FillFromRange Sheet1.ListObjects("tblCountries").DataBodyRange

    For Each rCell In Sheet2.Range("A3:A5").Cells
        Set clsCountry = Nothing
        Set clsCountry = clsCountries.CountryBy("Code", CStr(rCell.Value))

        If Not clsCountry Is Nothing Then
            rCell.Offset(0, 1).Value = clsCountry.Fullname
            rCell.Offset(0, 2).Value = clsCountry.Abbreviation
        End If
    Next rCell

End Sub

除了定义我在其中循环的代码的位置之外,我真的不需要任何评论。您可以告诉我对象的名称以及属性或方法的内容。这是设置课程模块的额外工作的回报 - IMO。

答案 1 :(得分:1)

您可以拥有对象或词典的字典。

  

VBA有几种存储数据的方法:

     
      
  • a Dictionary
  •   
  • a Collection
  •   
  • 一个数组(矩阵)变量
  •   
  • ActiveX ComboBox
  •   
  • ActiveX ListBox
  •   
  • 一个Userform控件ComboBox
  •   
  • 一个Userform控件ListBox
  •   
  • a sortedlist
  •   
  • 一个arraylist
  •   

我建议你阅读以下文章:

http://www.snb-vba.eu/VBA_Dictionary_en.html

相关问题