2015-12-07 111 views
0

我正在嘗試創建列表字典。我習慣於在python中,但在vba我有困難。 的數據是在列A和B(我將使用與終端(xldown的範圍),而不是硬編碼A1:A4這只是舉例),他們是這個樣子:使用VBA創建字典

A Apple 
A Banana 
B Carrot 
B Juice 

基本上我」我想創建一個字典,看起來(在Python格式爲:{A:[Apple,Bannana],B:[Carrot,Juice]}

最終的結果是我想粘貼字典值另一列C將如下所示:

A Apple Apple/Banana 
A Banana Apple/Banana 
B Carrot Carrot/Juice 
B Juice Carrot/Juice 

我一直在嘗試neste d通過varrays循環但它沒有識別出列A和B的相對位置。我想知道在VBA中執行此操作的最佳方式是什麼?
謝謝。

回答

1

您可以只使用VBA或與UDF混合使用。

考慮最初你有(證明的選項之一):
sampledata

創建一個模塊,並把這個在:

Option Explicit 

Private lRow As Long 
Private oDict As Object 

Private Sub CreateDict() 
    Dim arrValues As Variant, oKey As Variant, oValue As Variant, i As Long 

    If oDict Is Nothing Then 
     lRow = Worksheets("Sheet2").UsedRange.Rows.Count 
     Set oDict = CreateObject("Scripting.Dictionary") 
    Else 
     If lRow <> Worksheets("Sheet2").UsedRange.Rows.Count Then oDict.RemoveAll ' Remove old items 
    End If 
    ' Add items to the dictionary 
    ' Load values of used range to memory 
    arrValues = Worksheets("Sheet2").UsedRange.Value 
    ' Assuming the Key is on first column and Value is on next 
    For i = 1 To UBound(arrValues) 
     oKey = arrValues(i, 1) 
     oValue = arrValues(i, 2) 
     If Len(oKey) > 0 Then 
      If oDict.Exists(oKey) Then 
       ' Append Value to existing key 
       oDict.Item(oKey) = oDict.Item(oKey) & "/" & oValue 
      Else 
       ' Add Key and value 
       oDict.Add oKey, oValue 
      End If 
     End If 
    Next 
End Sub 

Function GetList(ByVal oRange As Range) As String 
    If lRow <> Worksheets("Sheet2").UsedRange.Rows.Count Then Set oDict = Nothing 
    If oDict Is Nothing Then CreateDict 
    GetList = oDict.Item(oRange.Value) 
End Function 

上面的宏是創建字典列表。然後在下一列中使用公式調用UDF GetList,例如
Stage1

自動填充的UDF得到的結果你想要的:
Stage2


有優點和缺點使用UDF,但我相信你可以將它修改爲僅VBA(新Sub和循環遍歷第一列)。

+0

這非常重要。所以那麼我的問題是,你必須明確地確保引用在數組中通過使用arrValues。非常感謝您的學習重點。是的,很容易將其修改爲VBA,但很高興看到該選項。 – FancyDolphin

+0

您可以將任何範圍值加載到內存中並處理它們,難的部分是確定除行之外的列數。 – PatricK

-1

使用公式和VBA的組合可以實現預期的結果。在開始細胞C1然後向下拖動到表格處的端部下面的公式:

=stringconcat("/",IF($A:$A=A1,$B:$B,"")) 

此插入作爲使用CTRL + SHIFT + ENTER數組公式。解釋來自IF的邏輯,對於列A:A中等於該行值(在所提供的示例中爲「A」)中的每一行,它將其提取到數組中(如果在IF中爲true,則返回)。最好的部分是,您不必在考慮整列時對範圍進行硬編碼。

然後陣列採用芯片Pearsons方便的功能,你可以在這裏找到級聯:

http://www.cpearson.com/excel/stringconcatenation.aspx

包括他親切地提供到模塊的代碼,你是去比賽。

+0

雖然awnser非常感謝,但如果我要去電子表格路線它可以做得更簡單。我可以創建一個唯一索引,使用一些長度計數器並與if命令連接。然而,這很麻煩,我寧願它僅由VBA在一個有效的數據範圍內完成,而不是整個列將佔用相當一部分資源。 – FancyDolphin

0

正如PatricK已經表明的那樣,VBA中有字典,但只能通過腳本編寫,而不是像Python中一樣很好地集成到語言中(上帝,我想念那些列表和字典)。正如PatricK所示,該方法通常可行,但需要引用腳本或使用後期綁定。

作爲替代方案,您可以使用類的集合。定義一個類模塊,並給它一些變量,其中一個集合。這樣,您可以遍歷您的類集合以查找索引字母(本例中爲A和B),並從存儲的類中提取水果列表。

我覺得這個方法更加靈活和可擴展(你可以完全控制類模塊)。它是一種「原生」解決方案,可以在任何機器上運行,也可以在Mac上運行(有時引用可能會很痛苦)。

如果你願意,我可以用一個例子來闡述,但我永遠不可能像Chip Pearson在他的site上那樣完整。

+0

非常好的指針,用於高級使用VBA和Mac不友好的代碼......您是否使用Collection實現Scripting.Dictionary找到現有代碼?有許多方法可能會讓Mac變得過於繁瑣。 – PatricK

+0

確實如此,有時不值得一提。但是,10次中有9次使用Dictionary I,因爲我想做一些Dictionary不能做的事情。而一個類的集合並沒有那麼麻煩。你知道你可以將一個鍵分配給vba中的一個集合變量嗎?大部分時間不是非常有用,但在某些情況下仍然有用。 – Jzz