Microsoft Excel

Herbers Excel/VBA-Archiv

Werte in Array in Dictionary eintragen

Betrifft: Werte in Array in Dictionary eintragen von: Ben.Blake
Geschrieben am: 31.10.2020 12:44:41

Hallo,


ich hab mal wieder ein Problem(chen). Ich habe diverse benannte Bereiche, die ich einige hundert Mal abfragen muß. Deshalb hab ich die in Arrays gepackt. Allerdings sind dort in einzelnen (leeren) Zellen auch Farbinformationen, die dabei natürlich verloren gehen.

Also wollte ich die Bereiche dann nochmal abgrasen und die Farbwerte dann in die Arrays übertragen.


Da das ja für verschiedene Arrays und Bereiche immer wieder der gleiche Vorgang ist, bietes sich da ja eine Schleife an. Also hab ich ein bisschen gesucht und bin auf das Dictionary-Objekt gestoßen. Wenn ich da die einzelnen Felder einfach mit Zahlen versehe, müßte ich ja so dann per Schleife die Arrays wechseln können.


Das funktioniert soweit super. Aber sobald ich dann in das Array-Feld den Farbwert eintragen will, passiert nichts - das Feld bleibt leer.


Gibt es da einen besonderen Kniff und ist es überhaupt möglich, in Arrays in Dictionaries nachträglich Werte einzutragen (nicht anzuhängen sondern den Wert es Feldes zu ersetzen)? Dazu hab ich nämlich nichts gefunden. Soweit ich das verstanden habe, ist das Dictionary ja nur ein Index auf verschiedene Arrays, so daß ja das Array direkt angesprochen wird, also müßte es ja eigentlich funktionieren...


Vielen Dank schonmal


Gruß

Ben

Betrifft: AW: Werte in Array in Dictionary eintragen
von: Daniel
Geschrieben am: 31.10.2020 12:56:35

Hi

Wie machs du das?
Was in der Regel funktioniert ist folgende:
Array aus Dictionary in ein normales Array kopieren.
Im normalen Array die Werte ändern.
Geändertes Array ins Dictionary zurückschreiben.

Gruß Daniel

Betrifft: AW: Werte in Array in Dictionary eintragen
von: Ben.Blake
Geschrieben am: 31.10.2020 13:41:33

Danke für die schnelle Antwort.

Ich hab natürlich noch weiter gesucht und dann hier das: https://www.herber.de/forum/archiv/1220to1224/1222541_Schreibzugriff_auf_Array_in_Dictionary_ObjectItem.html gefunden und es dann genauso gelöst, wie Du es schreibst - ein zusätzliche Array angelegt, das aktuelle Dictionary-Array übertragen, den Eintrag aus dem Dictionary entfernt, den Wert in das zusätzlichen Array eingetragen und dann dieses an der gleichen Stelle wieder in das Dictionary "geaddet". Für die, die das gleiche Problem haben sollten:

Ich hatte dabei noch einen Fehler gemahct und die Arrays mit DicAr(#) = Array zugewiesen, was zwar erstmal funktionierte aber dann beim Ersetzen Probleme machte. Es sieht jetzt so aus:
Sub FarbwerteUebertragen()

Dim DicAr As Object
Dim cARng
Dim VerglListe

Rng1 = "Rng1"
Rng2 = "Rng2"
Rng3 = "Rng3"
Rng4 = "Rng4"

'Anlegen eines Arrays mit den Bereichsnamen um in der Schleife drauf zugreifen zu können
cARng = Array(Rng1, Rng2, Rng3, Rng4)
Arr1 = Range(Rng1)
Arr2 = Range(Rng2)
Arr3 = Range(Rng3)
Arr4 = Range(Rng4)

'Vergleichsliste in der gesucht wird, ob die Überschrift vorhanden ist und ob da Farbe drin  _
steckt
VerglListe = Range("Vergleichsliste")

Set DicAr = CreateObject("Scripting.Dictionary")

DicAr.Add "A1", Arr1
DicAr.Add "A2", Arr2
DicAr.Add "A3", Arr3
DicAr.Add "A4", Arr4


For i = 1 To 4
    j = 0
    Do: j = j + 1
        'Leere Tabellenüberschriften werden übersprungen
        If DicAr("A" & i)(1, j) <> "" Then
            'Suchen in Überschriften ob Spalte mit Farben
            k = 0
            Do: k = k + 1
                fnd = False
                If DicAr("A" & i)(1, j) = VerglListe(k, 1) And InStr(1, VerglListe(k, 1), " _
Marker", 0) <> 0 Then
                    fnd = True
                End If

                'Wenn eine gefunden, dann abgrasen der Zellen
                If fnd Then
                    L = 0
                    Do: L = L + 1
                        DicAr("A" & i)(1, j) = 1
                        'Wenn Zelle nich farblos, dann Zellfarbe auslesen und in Array-Feld  _
schreiben
                        If Range(cARng(i)).Cells(L, 1) <> "" And Range(cARng(i)).Cells(L, k). _
Interior.ColorIndex <> xlNone Then
                            XArray = DicAr("A" & i)
                            DicAr.Remove ("A" & i)
                            XArray(L, k) = Range(cARng(i)).Cells(L, k).Interior.Color
                            DicAr.Add "A" & i, XArray
                            CTD = DicAr("A" & i)(L, k)
                        End If
                    
                    Loop Until L = UBound(DicAr("A" & i), 1)
                End If
            Loop Until k = UBound(VerglListe, 1) Or fnd
            
        End If
    
    Loop Until j = UBound(DicAr("A" & i), 2)

Next i

End Sub
Ich hab es hierfür umgeschrieben, es können also Fehler drin sein aber das Prinzip sollte passen...

Gruß
Ben

Betrifft: AW: Werte in Array in Dictionary eintragen
von: Ben.Blake
Geschrieben am: 31.10.2020 13:45:43

Noch ein Fehler gefunden: die k-Schleife wird nicht bei fnd abgebrochen...

Betrifft: AW: Werte in Array in Dictionary eintragen
von: Daniel
Geschrieben am: 31.10.2020 13:58:58

Hi
Schön wenns klappt.

Ich schau mir das jetzt nicht im Detail an, aber:
Warum verwendest du nicht die Bereichsnamen als Key?
Dann könntest du leichter von den Dictionary-Werten aus den Zellbereich zurückschließen, falls du das mal brauchst.

Die Schleife über alle dictionay-Einträge geht dann so, wenn die Keys nicht durchnummeriert sind:
Dim K 
For each K in Dict.Keys
   Dict(K) ist dann der jeweilige Eintrag
Denn wenn du die Keys durchnummerierst um dann mit einer einfachen Zählschleife durch das Dictionary zu laufen, könntest du das auch mit einem einfachen eindimensionalen Array erledigen.
Das Dictionary setzt man ein, wenn die Keys beliebige freitexte sind. Sobald sich die Keys ohne großen Aufwand durch eine Ganzzahlfolge darstellen lassen, ist ein Normales Array die bessere Lösung.

Gruß Daniel

Betrifft: AW: Werte in Array in Dictionary eintragen
von: Ben.Blake
Geschrieben am: 31.10.2020 15:03:13

Ich hab den Code nur gepostet für den Fall, daß jemand ein ähnliches Problem hat - ich hab nämlich ne ganze weile suchen müssen...
Und mittlerweile hab ich auch die restlichen Fehler gefunden, es läuft, wie es soll.

Was Du schreibst, ist mir nicht so richtig klar. Ich bin dieser "For each x in y" Konstruktion nur einmal bei einer Dateisuche begegnet und da war es um Welten langsamer als Dir - Auf Deutsch: Ich werd da nicht so richtig schlau draus ;)

Das K ist dann aber keine Integer-Variable sondern die Namen, oder?
Da ich ja parallel die Bereichsnamen in einem eindimensionalen Array hab un dann drauf zugreifen zu können brauch ich ja eine Integer-Variable. Oder könnte ich dann einfach Range(K) nutzen? Das wäre natürlich weniger umständlich.

"Denn wenn du die Keys durchnummerierst um dann mit einer einfachen Zählschleife durch das Dictionary zu laufen, könntest du das auch mit einem einfachen eindimensionalen Array erledigen.
Das Dictionary setzt man ein, wenn die Keys beliebige freitexte sind. Sobald sich die Keys ohne großen Aufwand durch eine Ganzzahlfolge darstellen lassen, ist ein Normales Array die bessere Lösung."

Das war ja meine erste Idee aber da bin ich auf nix gekommen. Damit, nicht das volle Potential eines Dictionaries ausgenutzt zu haben, käme ich klar ;). Ich hab das Dictionary dann genutzt, weil ich die gleiche Funktion nicht für alle Arrays gesondert schreiben wollte und eben in der Schleife auf die Namen der Arrays zugreifen mußte. Wenn es da noch eine andere Möglichkeit gäbe, wäre ich ganz Ohr... ;)

Die Übersichtlichkeit ist in diesem Falle kein Thema. Sobald das durchgerattert ist, werden die Dic-Arrays wieder zurückgeschrieben und das Dictionary ist dann Geschichte...

Betrifft: AW: Werte in Array in Dictionary eintragen
von: Daniel
Geschrieben am: 31.10.2020 15:14:40

"Oder könnte ich dann einfach Range(K) nutzen? "

Genau das.

Gruß Daniel

Betrifft: AW: Werte in Array in Dictionary eintragen
von: Ben.Blake
Geschrieben am: 31.10.2020 16:01:35

Das hab ich dann mal mit in meine Verbesserungsliste genommen, Danke.

Und was meintest Du mit "Denn wenn du die Keys durchnummerierst um dann mit einer einfachen Zählschleife durch das Dictionary zu laufen, könntest du das auch mit einem einfachen eindimensionalen Array erledigen." - da werd ich auch noch nicht ganz schlau draus...

Gruß
Ben

Betrifft: AW: Werte in Array in Dictionary eintragen
von: Daniel
Geschrieben am: 31.10.2020 18:20:30

So wie du das Programmiert hast, brauchst du kein Dictionary.

Du kannst dein DicAr auch als Dim DicAr(1 to 4) as Variant deklarieren und als Index 1, 2, 3 und 4 anstelle von "A1", "A2", "A3" und "A4" verwenden und es funktioniert genau so.

Gruß Daniel

Betrifft: AW: Werte in Array in Dictionary eintragen
von: Ben.Blake
Geschrieben am: 31.10.2020 18:51:33

Also Arrays in einem Array? Und dann sicherlich mit DicAr(#) = Arr# usw. die Arrays reinpacken? Genau danach hatte ich ja gesucht.

Hab mir gerade mal einen Testprogramm gemacht, die Notation mit DicAr(1)(1)(1) statt DicAr(1)(1,1) ist ein bisschen gewöhnungsbedürftig aber es scheint zu funktionieren...

Danke!

Betrifft: AW: Werte in Array in Dictionary eintragen
von: Daniel
Geschrieben am: 31.10.2020 19:06:19

Hi
Ja auch in ein Array kannst du nicht nur Einzelwerte reinpacken, sondern auch weitere Arrays beliebiger Dimension.
Gruß Daniel

Betrifft: Korrektur ist einfach, ...
von: Luc:?
Geschrieben am: 31.10.2020 13:26:17

…Ben:
    Dim dx As Dictionary   'bei Verweis auf Scripting.Runtime
    Set dx = CreateObject("Scripting.Dictionary")
    dx.Add "alfa", 11
    Debug.Print dx("alfa")
    dx("alfa") = 22
    Debug.Print dx("alfa")
Ggf noch eine Verzweigung einbauen, dass nur falls der Key bereits existiert so geändert, ansonsten aber hinzugefügt wird.
Gruß, Luc :-?
„Die universelle Befähigung zur Unfähigkeit macht jede menschliche Leistung zu einem unglaublichen Wunder.“ Stapps ironisches Paradoxon

Beiträge aus dem Excel-Forum zum Thema "Werte in Array in Dictionary eintragen"