索引为

时间:2018-03-06 17:26:50

标签: arrays excel vba excel-vba

这是我关于stackoverflow的第一个问题,我非常乐意接受有关如何/何时/何时提出更好的问题以及如何更好地为stackoverflow做出贡献的反馈。

背景
我的最终目标是在各个测试实验室按日期绘制预计的设备使用情况。

我在几个实验室使用相同的设备,我正在创建一张表格,向我展示每个实验室设备使用情况的未来预测。

我的开头:
我有一份包含多个工作表的Excel文档,每个工作表都包含有关在哪个测试机构在哪个时间段内使用哪些设备的信息。

我的目标:
为每个测试实验室创建设备使用情况图表。该图表将显示在给定日期使用的每件设备的数量。我的目的是为每种类型的设备制作一个图表系列,其中日期为X轴,Y轴上使用的设备数量。

我做得很远:
我编写了循环遍历所有信息表的代码,并创建了每个独特测试实验室名称的vba集合,以及我想要跟踪的每个独特设备的单独vba集合。此代码还可以找到使用任何设备的第一个日期和最后日期。

帮助请求:
因为我基本上有三个"尺寸" - 测试实验室,设备和设备使用日期 - 我曾计划使用3D阵列来聚合我的所有数据并提供我的使用图表的来源。这个数组将设备作为一个维度,日期作为第二个,测试实验室作为第三个。

然而,正如我已经考虑过这个实现,它似乎相当笨拙。它将保存我的所有数据,但据我所知,我无法通过键或标签来引用数组的元素。我必须创建单独的2D数组来保存3D数组的每个维度的索引标签。

Excel VBA中是否有支持每个维度的索引键的3D数据结构?

搜索和尝试失败:
我首先尝试创建一个独特的数组来保存设备和使用日期,每个数组都以一个独特的测试实验室命名。我从这篇文章中了解到,我无法动态创建并命名一个未定义数量的新数组:Naming an array using a variable

然后我研究了是否可以使用我已创建的集合以某种方式作为数组索引的标签,但似乎我无法通过键找到集合索引。每次我想引用3D数组中的元素时,我都必须遍历集合才能找到索引:Retrieve the index of an object stored in a collection using its key (VBA)

2 个答案:

答案 0 :(得分:1)

如果您需要按键调用集合,则应该将该集合声明为字典。

Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
dict(Key) = Value

它比集合强大得多。我希望有所帮助。

完整信息: https://excelmacromastery.com/vba-dictionary/

答案 1 :(得分:0)

我从收到的所有评论和答案中实施了信息。谢谢Jeremy,Victor K和HackSlash!

这里的解决方案简而言之:用户定义数据类型的数组,包含用户定义数据类型的数组,其中包含脚本字典,即字典数组数组。我还创建了用于检索数据的参考词典。 (参见下面的工作示例)

首先,要在VBA中使用脚本词典,请转到工具>引用并选中“Microsoft Scripting Runtime”旁边的框。我在这里学到了这一点:Does VBA have Dictionary Structure?。我还了解到,如果工作表已分发,则包含此设置(其他人不必进入VBA并在使用工作表之前选中复选框):http://www.snb-vba.eu/VBA_Dictionary_en.html

Public Type ItemTracked
    ItemName As String
    UseDates As Scripting.Dictionary
End Type

Public Type TrackingStructure
    TestLab As String
    TrackedItems() As ItemTracked
End Type

Sub Tracking()

Dim TrackingArr() As TrackingStructure

'**************
'Example Data
'**************
    'Create array of example dates
    Dim DateArray As Variant
    DateArray = Array(43164, 43171, 43178) 'Excel date codes for 3/5/2018, 3/12/2018, and 3/19/2018

    'Create array of example equipment
    Dim EquipArray As Variant
    EquipArray = Array("Cooling Pump", "Heating Pad", "Power Supply")

    'Create array of example number of pieces of equipment in use
    Dim UseArray As Variant
    UseArray = Array(0, 1, 2)

    'Create array of example test lab names
    Dim LabNames As Variant
    LabNames = Array("LabABC", "Lab123", "LabDOREMI")

'**************
'Creating and Populating Data Structure
'**************

    'Create array of TrackingStructure Type with space to track test labs
    ReDim TrackingArr(UBound(LabNames))

    'Loop through TrackingArr to populate usage for each test lab
    For i = LBound(TrackingArr) To UBound(TrackingArr)

        'Record lab name
        TrackingArr(i).TestLab = LabNames(i)

        'Redimension size of TrackedItems to accomodate example equipment
        ReDim TrackingArr(i).TrackedItems(UBound(EquipArray))

            'Loop through EquipArray for each test lab
            For j = LBound(EquipArray) To UBound(EquipArray)
                Set TrackingArr(i).TrackedItems(j).UseDates = New Scripting.Dictionary
                TrackingArr(i).TrackedItems(j).ItemName = EquipArray(j)

                'Loop through dates and usage for each piece of equipment
                For k = LBound(DateArray) To UBound(DateArray)
                    'Populate date and equipment use
                    TrackingArr(i).TrackedItems(j).UseDates.Add DateArray(k), UseArray(k)
                Next k
            Next j
    Next i

'**************
'Referencing Data
'**************

'Create and Populate Dictionaries for Use in Referring to Data
Set LabNamesRef = New Scripting.Dictionary
Set EquipArrayRef = New Scripting.Dictionary

For i = LBound(TrackingArr) To UBound(TrackingArr)
    LabNamesRef.Add TrackingArr(i).TestLab, i
Next i

For i = LBound(EquipArray) To UBound(EquipArray)
    EquipArrayRef.Add EquipArray(i), i
Next i

'Demonstration Print of Entire Data Structure
For i = LBound(TrackingArr) To UBound(TrackingArr)
    Debug.Print "Lab Name: " & TrackingArr(i).TestLab
    For j = LBound(TrackingArr(i).TrackedItems) To UBound(TrackingArr(i).TrackedItems)
        Debug.Print TrackingArr(i).TrackedItems(j).ItemName
        For k = 0 To TrackingArr(i).TrackedItems(j).UseDates.Count - 1
            Debug.Print TrackingArr(i).TrackedItems(j).UseDates.Keys(k), TrackingArr(i).TrackedItems(j).UseDates.Items(k)
        Next k
    Next j
Next i

'Access One Example Entry
Debug.Print "Lab Name:" & TrackingArr(LabNamesRef("Lab123")).TestLab
Debug.Print "Equipment:" & TrackingArr(LabNamesRef("Lab123")).TrackedItems(EquipArrayRef("Cooling Pump")).ItemName
Debug.Print "Usage on Date 43164: " & TrackingArr(LabNamesRef("Lab123")).TrackedItems(EquipArrayRef("Cooling Pump")).UseDates(43164)

End Sub