2015-04-02 114 views
0

由於這些是我一次使用的2-3個新概念,因此我很難處理這個特定問題。我是新來的集合和類,過去只做過動態數組(我知道,很多「Redim蜜餞」)。這已經足夠了,但我終於到了需要更強大的東西來處理我的列表的地步。創建對象集合,然後在Excel VBA集合中查找匹配

要設置,我需要創建一個名爲動態列表的動態列表,然後才能讀出來。

實施例: 想象三明治配料,電子表格,其中A欄是成分與B列是夾心名稱。 (三明治的數量和每個三明治配料的數量是未知的,因此,所有動態的煩躁。)

我需要往下走行和閱讀夾層式。 如果已經有這個名字的三明治,那麼在三明治的名單末尾添加配料。如果不是,請創建一個新列表。

在它的結束,經過三文治並打印出成分的每個人的名單。

我想我需要製作一個「三明治」對象的「三明治」集合,並且我已經獲得了開始一個「CSandwich」類,「Public property get Name()as string」。但後來我失去了關於如何使一個的成份陣列或者甚至什麼樣的數據類型的使用...

感謝

+0

VBA是一個相當原始的語言。你究竟需要怎樣處理這些數據?聽起來更像是一個Access或其他基於SQL查詢的系統的項目。 – clum 2015-04-02 21:15:06

+0

雖然我同意你的看法,但我還必須補充一點,這是一個已經開始並用VBA編寫的大型項目的契機。 (你應該在看到它之前看到它。) 我最終會改寫它更強大的東西,但就目前來看,這是我的工作。 – Jongscx 2015-04-03 13:22:57

回答

1

我clum同意。 VBA對許多任務來說非常方便,但它不適用於任何任務。就我個人而言,我發現它的處理非常笨拙。

下面的代碼可以完成您使用Collections查找的內容,但不包含類。現在嘗試收藏,一旦你感覺舒服,就考慮學習課程。您也可能希望調查與集合類似的字典,並且可能更適合您當前的要求。

爲了檢驗和證明我的家常便飯,我創建了一個包含一個工作表:

Sample data

由於我打字,這個我重讀你的問題。我看到我把這些列倒過來,但我決定不修復這些。

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 
+0

「Inx」是增量計數器嗎? 「InxS」和「InxI」分別是增量夾心和增量配料? – Jongscx 2015-04-03 13:35:20

+0

@JosephLopez。我有一個多年來使用的命名約定,這意味着我可以查看我在2005年編寫的宏,並知道所有變量是什麼。更新舊宏時非常有用。 「三明治」是一個例外,但我的大部分變量名都是一系列單詞。 – 2015-04-03 15:51:06

+0

第一個單詞告訴我何時使用變量;每個後續單詞縮小範圍,直到名稱是唯一的。 「Inx」告訴你它是一維數組或集合的索引。 「行」告訴你它是一排工作表或二維數組。 「我」是成分的簡稱,「三明治」的「S」(正如你猜測的),並告訴你他們是什麼樣的指標。 – 2015-04-03 15:51:40