Erstellen Wörterbuch der Listen in vba
Habe ich in Python früher, wo es wirklich glatt haben ein Wörterbuch von Listen (D. H. eine Taste entspricht einer Liste von Sachen). Ich bin kämpfen, um das gleiche zu erreichen in vba. Sagen, ich habe die folgenden Daten in einem excel-sheet:
Flanged_connections 6
Flanged_connections 8
Flanged_connections 10
Instrument Pressure
Instrument Temperature
Instrument Bridle
Instrument Others
Piping 1
Piping 2
Piping 3
Nun möchte ich die Daten Lesen und speichern Sie es in einem Wörterbuch, wo die Schlüssel sind Flanged_connections
, Instrument
und Piping
und die Werte sind die entsprechenden Werte in der zweiten Spalte. Ich möchte die Daten wie folgt Aussehen:
'key' 'values':
'Flanged_connections' '[6 8 10]'
'Instrument' '["Pressure" "Temperature" "Bridle" "Others"]'
'Piping' '[1 2 3]'
und dann in der Lage sein, um die Liste zu tun dict.Item("Piping")
mit der Liste [1 2 3]
als das Ergebnis. Also ich dachte etwas wie:
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
Dies scheint ein wenig langweilig zu tun. Gibt es eine bessere Vorgehensweise? Ich habe versucht, die Suche für die Verwendung von arrays in vba und es scheint ein bisschen anders als java, c++ und python, mit stuft, wie redim preserve
und der gleichen. Ist dies der einzige Weg, um die Arbeit mit arrays in vba?
Meine Lösung:
Basierend auf @varocarbas' Kommentar habe ich erstellt, ein Wörterbuch der Sammlungen. Dies ist die einfachste Methode für meine Gedanken, um zu begreifen, was Los ist, obwohl es möglicherweise nicht die effizienteste sein. Die anderen Lösungen würden wohl so gut funktionieren (nicht getestet von mir). Das ist mein Lösungsvorschlag und liefert die korrekte Ausgabe:
'/--------------------------------------\'
'| 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
Beachten Sie, dass diese Lösung geht davon aus, dass alle Anlagen sind sortiert!
dict
Objekt kann nur die eindeutigen Schlüssel-Werte.können Sie nicht fügen Sie eine ID-Spalte und verwenden es als Schlüssel statt?
Können Sie das definitiv tun, und wenn Sie finden es zu ausführlich, dass ist leider die Natur von VBA, wenn im Vergleich zu einigen anderen Sprachen... Eine Sache, aber beachten Sie: versuchen Sie nicht, ändern Sie das array während es noch im Wörterbuch: Sie müssen ziehen Sie es durch die Zuweisung zu einer Variablen erweitern (mit Redim Preserve), und dann wieder weisen Sie es zurück, um das Wörterbuch.
Ja, schlechter Satz, dass das nicht jeder Wert auf die Frage. Es ist entfernt.
Was ist der Grund Sie können nicht ändern, die das array direkt? Etwas, das mit der übergabe per Referenz/Werte? Es scheint, wie dies der Fall für meine Lösung auch, mit der Sammlung gezogen werden Daten Hinzugefügt, entfernen Sie Sie aus dem Wörterbuch und fügen Sie es wieder in. Nicht, dass es darauf ankommt viel für an dieser Stelle, da diese statisch ist, nur-lese-Daten.
InformationsquelleAutor Krøllebølle | 2013-07-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Arrays in VBA sind mehr oder weniger wie überall sonst mit verschiedenen Besonderheiten:
Sheets
array in einer Arbeitsmappe) sind 1-basiert. Obwohl, wie zu Recht darauf hingewiesen hat @TimWilliams, die Benutzer-definierten arrays tatsächlich sind 0-basiert. Das array unten definiert ein string-array mit einer Länge von 11 (10 weist die Obere position).Andere als das und die Besonderheiten bei Schreibweisen, sollten Sie nicht finden, ein problem für den Umgang mit VBA-arrays.
In Bezug auf, was Sie fordern, können Sie erstellen ein Wörterbuch in VBA und enthalten eine Liste auf (oder der VBA-äquivalent:
Collection
), hier haben Sie ein Beispiel-code:Sie sind herzlich willkommen.
Arrays in VBA sind 0-basiert standardmäßig nicht 1-basiert, es sei denn, Sie verwenden
Option Base 1
.MsgBox LBound(Array(1,2,3))
geben0
Wenn Sie die dimension eines Arrays durch die Verwendung des oben genannten Anweisung ohne Ausführung jeglicher anderer Modifikation, bekommt er 1-base. Dieses array ist 1-Basis. Wenn Sie verlassen sich auf andere Dimensionierung (die array-Typ antwortete ich mit einem post auf diesen Linien mit den heutigen), es ist null Basis. Also ich glaube nicht, dass Sie taxative an dieser front. Was stimmt, ist, dass die meisten Eigenschaften in VBA sind 1-basiert, und die Art des Feldes habe ich in meinem Beispiel ist 1-Basis
Ich aktualisiert meine Antwort, ich hoffe, dass Sie aktualisieren Sie Ihre Aussage entsprechend (oder mir sagen, wo ich falsch bin).
InformationsquelleAutor varocarbas
Können Sie Wörterbücher in Wörterbüchern. Keine Notwendigkeit zur Verwendung von arrays oder Sammlungen, es sei denn, Sie haben eine spezifische Notwendigkeit zu.
Es ist das gleiche wie varocarbas' Antwort außer statt der Speicherung von Sammlungen in ein Wörterbuch, ich bin die Speicherung Wörterbücher in einem Wörterbuch. Ich weiß nicht, warum Sie verwenden würden, eine Sammlung, wenn Sie bereits einen Verweis auf die Scripting Runtime.
inwiefern ist das Wörterbuch dann besser Sammlung, so dass Sie sagen, Sie bevorzugen Dict, Wann immer möglich?
Zwei Dinge: die
Exists
Methode verhindert, dass die Fehlerbehebung Weg zu sehen, wenn etwas in die Sammlungen und, mein Favorit, die Sie verwenden könnenItems
oderKeys
, ein array zu erstellen. Sehr praktisch für das füllen einer combobox. Der Nachteil ist man kann nur hinzufügen, um das Ende des Stacks.InformationsquelleAutor Dick Kusleika
Ich bin nicht so vertraut mit C++ und Python (eine lange Zeit) also kann ich nicht wirklich sprechen, um die Unterschiede mit VBA, aber ich kann sagen, dass die Arbeit mit Arrays in VBA ist nicht besonders kompliziert.
In meiner eigenen bescheidenen Meinung nach, der beste Weg, um die Arbeit mit dynamischen arrays in VBA ist die Dimension, die Sie zu einer großen Nummer wird, und zu schrumpfen, wenn Sie fertig sind das hinzufügen von Elementen. Ja, Redim Preserve, wo Sie dimensionieren das array beim speichern der Werte, hat einen ENORMEN performance-Kosten. Sie sollten NIE mit Redim Preserve in einer Schleife, die Ausführung wäre quälend langsam
Passen Sie die folgende Stück code, als Beispiel:
ReDim Flanged_Connections(0 to wS.Cells(1, 1).CurrentRegion.Rows.Count)
am Anfang. Dies vermeidet die Notwendigkeit, verkleinern Sie das array am Ende, und nicht ein Durcheinander der code mit einer unnötigen Größe der Abtretung.Erhalten Sie ein array, das ist nicht die perfekte Größe, da es der Größe 10 in dem Beispiel, das er gab, statt der Größe 3. so werden Sie noch brauchen, es zu verkleinern, wenn Sie wollen, um zu verwenden, Ubound
Zeigen Sie, dass die meisten ideal richtig zu dimensionieren das array zunächst, D. H., einige Logik verwenden, um zu bestimmen, die entsprechenden
UBOUND
und dann festgelegt, dass zunächst. Vielleicht nicht anwendbar in diesem Fall, wenn dieUBOUND
können nicht im Voraus bestimmt werden von der Schleife. Cheers.Ich Stimme voll mit, (ich von Ihnen positiv bewertet werden Ihren Kommentar). Und in jedem Fall würde es besser sein, auf was Sie ursprünglich vorgeschlagen, statt mit einem beliebigen Wert, wie ich. Ich werde aktualisieren, meine Antwort mit einer ZÄHLENWENN
InformationsquelleAutor Julien Marrec