我在这个特定问题上遇到了困难,因为这些是我一次合作的2-3个新概念。我是集合和类的新手,过去只做过动态数组(是的,我知道,很多" Redim Preserves")。这已经足够了,但我终于到了需要更强大功能来处理我的名单的地步。
要设置,我需要创建一个命名动态列表的动态列表,然后按顺序读出它们。
实施例: 想象一下三明治成分的电子表格,其中A列是成分,B列是三明治名称。 (三明治的数量和每个三明治中的成分数量是未知的,因此都是动态的。)
我需要沿着排下去阅读三明治类型。 如果已经有这个名称的三明治,请将该成分添加到该三明治列表的末尾。如果没有,请创建一个新列表。
在它结束时,浏览三明治并打印出每个成分列表。
我想我需要做一个" Sandwiches"收集"三明治"对象和我已经开始了" CSandwich" class,with" Public属性将Name()作为字符串"。但后来我迷失了如何制作一个Ingredients数组甚至是什么数据类型......
由于
答案 0 :(得分:1)
我同意克鲁姆。 VBA对于许多任务非常方便,但它不适合每项任务。我个人认为它对课程的处理非常笨拙。
下面的代码执行您使用集合但不使用Classes的内容。现在尝试收藏,一旦你对它们感到满意,可以考虑学习课程。您可能还希望调查与集合类似的字典,并且可能更适合您当前的要求。
为了测试和演示我的例程,我创建了一个包含以下内容的工作表:
在我输入的时候,我重读了你的问题。我看到我的列被颠倒了,但我决定不解决这个问题。
Sub RecordSandI
读取每一行并调用AddSandI
以适当地存储行的内容。然后输出集合Sandwich
的内容给出:
Sandwich a has ingredients: 1 2 3
Sandwich b has ingredients: 3 4
Sandwich c has ingredients: 1 5 6
Sandwich d has ingredients: 2
Sandwich
是集合的集合。对于每个子集合,第一个元素是三明治名称,其余元素是成分。
正如我之前建议的那样,在尝试更复杂的事情之前,先看看你能走多远。
Option Explicit
Sub RecordSandI()
Dim InxI As Long
Dim InxS As Long
Dim RowCrnt As Long
Dim Sandwich As New Collection
With Worksheets("SandI")
RowCrnt = 2
Do While .Cells(RowCrnt, 1).Value <> ""
Call AddSandI(Sandwich, .Cells(RowCrnt, 1).Value, .Cells(RowCrnt, 2).Value)
RowCrnt = RowCrnt + 1
Loop
End With
For InxS = 1 To Sandwich.Count
Debug.Print "Sandwich " & Sandwich(InxS)(1) & " has ingredients:";
For InxI = 2 To Sandwich(InxS).Count
Debug.Print " " & Sandwich(InxS)(InxI);
Next
Debug.Print
Next
End Sub
Sub AddSandI(ByRef Sandwich As Collection, ByVal SandwichName As String, ByVal IngredientName As String)
Dim InxI As Long
Dim InxS As Long
Dim SandwichNew As Collection
For InxS = 1 To Sandwich.Count
If Sandwich(InxS)(1) = SandwichName Then
' This sandwich already recorded
For InxI = 2 To Sandwich(InxS).Count
If Sandwich(InxS)(InxI) = IngredientName Then
'Debug.Assert False
' Ingredient already recorded
Exit Sub
End If
Next
' New ingredient
Sandwich(InxS).Add IngredientName
Exit Sub
End If
Next
' New sandwich
Set SandwichNew = New Collection
SandwichNew.Add SandwichName
SandwichNew.Add IngredientName
Sandwich.Add SandwichNew
End Sub