Раньше я работал в Python, где действительно плавно иметь словарь списков (т.е. один ключ соответствует списку вещей). Я изо всех сил пытаюсь добиться того же в vba. Скажем, у меня есть следующие данные на листе excel:
Flanged_connections 6
Flanged_connections 8
Flanged_connections 10
Instrument Pressure
Instrument Temperature
Instrument Bridle
Instrument Others
Piping 1
Piping 2
Piping 3
Теперь я хочу прочитать данные и сохранить их в словаре, где ключи Flanged_connections
, Instrument
и Piping
, а значения - соответствующие во втором столбце. Я хочу, чтобы данные выглядели следующим образом:
'key' 'values':
'Flanged_connections' '[6 8 10]'
'Instrument' '["Pressure" "Temperature" "Bridle" "Others"]'
'Piping' '[1 2 3]'
а затем получить список, выполнив dict.Item("Piping")
со списком [1 2 3]
в качестве результата. Поэтому я начал думать о чем-то вроде:
For Each row In inputRange.Rows
If Not equipmentDictionary.Exists(row.Cells(equipmentCol).Text) Then
equipmentDictionary.Add row.Cells(equipmentCol).Text, <INSERT NEW LIST>
Else
equipmentDictionary.Add row.Cells(equipmentCol).Text, <ADD TO EXISTING LIST>
End If
Next
Кажется, это немного утомительно. Есть ли лучший подход к этому? Я попытался найти массивы в vba и, похоже, немного отличается от java, С++ и python, с stuft like redim preserve
и подобных. Это единственный способ работать с массивами в vba?
Мое решение:
На основе комментария @varocarbas я создал словарь коллекций. Это самый простой способ для моего разума понять, что происходит, хотя это может быть не самым эффективным. Другие решения, вероятно, будут работать (не проверены мной). Это мое предложенное решение, и оно обеспечивает правильный вывод:
'/--------------------------------------\'
'| Sets up the dictionary for equipment |'
'\--------------------------------------/'
inputRowMin = 1
inputRowMax = 173
inputColMin = 1
inputColMax = 2
equipmentCol = 1
dimensionCol = 2
Set equipmentDictionary = CreateObject("Scripting.Dictionary")
Set inputSheet = Application.Sheets(inputSheetName)
Set inputRange = Range(Cells(inputRowMin, inputColMin), Cells(inputRowMax, inputColMax))
Set equipmentCollection = New Collection
For i = 1 To inputRange.Height
thisEquipment = inputRange(i, equipmentCol).Text
nextEquipment = inputRange(i + 1, equipmentCol).Text
thisDimension = inputRange(i, dimensionCol).Text
'The Strings are equal - add thisEquipment to collection and continue
If (StrComp(thisEquipment, nextEquipment, vbTextCompare) = 0) Then
equipmentCollection.Add thisDimension
'The Strings are not equal - add thisEquipment to collection and the collection to the dictionary
Else
equipmentCollection.Add thisDimension
equipmentDictionary.Add thisEquipment, equipmentCollection
Set equipmentCollection = New Collection
End If
Next
'Check input
Dim tmpCollection As Collection
For Each key In equipmentDictionary.Keys
Debug.Print "--------------" & key & "---------------"
Set tmpCollection = equipmentDictionary.Item(key)
For i = 1 To tmpCollection.Count
Debug.Print tmpCollection.Item(i)
Next
Next
Обратите внимание, что это решение предполагает, что все оборудование отсортировано!