Array deklarieren, Doppelte Werte entfernen und ausgeben

  • Excel

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von petaod.

    Array deklarieren, Doppelte Werte entfernen und ausgeben

    Hallo Leute,

    ich weiß, es gibt viele Themen zu diesem Thema, aber ich habe google durchforstet und viele Themen hier gelesen und ich bin anscheinend zu blöd die Puzzelteile zusammen zusetzen.

    Hier erstmal der Code, den ich bisher habe:

    VB.NET-Quellcode

    1. Dim arr() As Variant
    2. arr = Worksheets("Level3").Range("D62:D80")
    3. Dim objAL As Object
    4. Dim Lz As Long
    5. Set objAL = CreateObject("System.Collections.Arraylist")
    6. For Lz = 0 To UBound(arr)
    7. If objAL.Contains(arr(Lz)) = False Then
    8. objAL.Add arr(Lz)
    9. End If
    10. Next
    11. Erase arr
    12. With objAL
    13. .Sort
    14. arr = .ToArray
    15. End With
    16. Set objArrayList = Nothing
    17. '//Zum Test die Werte im Array ausgeben
    18. Dim ArrayTest As Worksheet
    19. Sheets.Add After:=ActiveSheet
    20. ActiveSheet.Name = "ArrayTest"
    21. Set ArrayTest = ThisWorkbook.Sheets("ArrayTest")
    22. Dim bla As Integer
    23. For bla = 1 To UBound(arr)
    24. ArrayTest.Cells(bla, 3).Value = arr(bla)
    25. Next


    Wie ihr vielleicht schon erkennt möchte ich eine Range in ein Array speichern, in dem Array dann die doppelten Werte entfernen, sortieren.
    Für mich, zur kontrolle, möchte ich dann die Werte aus dem Array in einem neuen Tabellenblatt ausgeben.
    Die Range ist so krum festgelegt, da es in diesen 19 Zeilen 19 einträge gibt, aber nur 3 einzelne Werte. Normalerweiße geht die Range bis 10000 hoch, aber wenn es in dieser kleinen Range funktioniert, dann auch in der großen.

    Das erstellen von dem neuen Worksheet funktioniert gut, der Rest anscheinden gar nicht. Ich bin auch mittlerweile Ratlos.
    Ich weiß nicht ob die Range sauber ins Array gespeichert wird, ob die For-Schleifen richtig beschrieben sind. Mit einer ArrayList habe ich auch noch nicht gearbeitet, daher auch ein großes ? ob das richtig definiert ist.

    Es sind alles Puzzelteile, die ich aus mehreren Beträgen zusammengetragen habe und bisschen angepasst habe.

    Ich hoffe ihr könnt mir helfen :)
    komplette Range in das neue Tabellenblatt kopieren und mit Range.RemoveDuplicates nachbearbeiten.
    Keine ArrayList, kein Schnickschnack.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    VaporiZed schrieb:

    komplette Range in das neue Tabellenblatt kopieren und mit Range.RemoveDuplicates nachbearbeiten.
    Keine ArrayList, kein Schnickschnack.


    Okay, hab das mal gemacht. Dachte das dauert aufgrund der Menge an Daten lane, aber ging doch erstaunlich in paar sekunden.

    Hier jetzt mein Code:

    VB.NET-Quellcode

    1. Dim ArrayTest As Worksheet
    2. Sheets.Add After:=ActiveSheet
    3. ActiveSheet.Name = "ArrayTest"
    4. Set ArrayTest = ThisWorkbook.Sheets("ArrayTest")
    5. '/Neues Arbeitsblatt erstellen
    6. Dim rng As Range
    7. Set rng = Worksheets("Level3").Range("D62:D7942")
    8. rng.ClearComments
    9. rng.Copy (ArrayTest.Cells(1, 1))
    10. '/Range festlegen, Kommentare entfernen und in das neue Blatt kopieren
    11. ActiveSheet.Range("A1:A8000").RemoveDuplicates (Array(1))
    12. '/Duplikate entfernen
    13. Dim rngEnde As Long
    14. rngEnde = ArrayTest.UsedRange.Rows.Count
    15. '/UsedRange ermitteln und zuweisen
    16. '/Kein Fehler bis hier
    17. Dim arr() As Variant
    18. arr = ArrayTest.Range("A1", "A" & rngEnde)


    Ist die zuweisung ins Array so korrekt? Oder muss das durch eine For-Schleife geregelt werden?

    EDIT:

    Ich hab da nun mal etwas rumprobiert, die Werte ins Array zu bekommen und mal Testweiße über eine For-Schleife auszugeben.
    Code sieht wie folgt aus:

    VB.NET-Quellcode

    1. Dim arr() As Variant
    2. arr = ArrayTest.Range("A1:A2039")
    3. ReDim arr(rngEnde)
    4. 'Testzwecke
    5. Dim jza As Long
    6. jza = 0
    7. For i = LBound(arr) To UBound(arr)
    8. jza = jza + 1
    9. ArrayTest.Cells(jza, 4).Value = arr(i)
    10. ArrayTest.Cells(jza, 5).Value = i
    11. Next


    In Spalte 5 stehen die erwarteten i-Werte, aber in Spalte 4 steht nix.
    Speichert er die Werte nicht richtig ins Array oder ist mein Befehl fürs "in die Zelle schreiben" falsch?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „lanbo“ ()

    Wenn Du bei Deinem Code bleiben willst, dann führt ReDim arr(rngEnde) in Zeile 3 des letzten Codeblocks zu einem großen, aber leeren Array. Du musst ReDim Preserve arr(rngEnde) verwenden, damit der Inhalt soweit erhalten bleibt.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Das mit dem Array läuft nun reibungslos. Der Zeitaufwand ist auch schön gering.
    Da ich nun mit den Werten im Array eine For-Schleife fütter, die viel kopiert, löscht, Werte vergleicht und rechnet, ist das noch ein großer Zeitfresser. Bzw ein Schleifendurchlauf dauert sehr lange.

    Ich frag mich nun ob VBA oder VSTO schneller ist. Was ist da so eure Erfahrung?

    Ich würde auch gerne die For-Schleife optimieren, die hat allerdings ein Kollege geschrieben der gerade im Urlaub ist.
    Die hat er nicht sauber kommentiert bzw. die Übergabe war nicht gut. Ich kann das schlecht nachvollziehen, wo die For-Schleife nun die Werte herholt, vergleicht und rechnet etc.
    Also fällt das erstmal flach.
    Hi,

    erstmal noch zu deinem Code oben.
    Die Copy Methode ist meiner Erfahrung nach nicht sehr performant. Du kannst stattdessen (wenn es dir nur um Werte geht) einfach beispielhaft Worksheet1.Range("A1:C19").Value = Worksheet2.Range("A1:C19").Value verwenden.
    Dann sollten auch Kommentare nicht kopiert werden.

    Zu deiner Frage mit VSTO vs VBA kommt es drauf an. VSTO ist generell vll etwas schneller, solange du nicht auf Excel zugreifst.
    Der Zugriff ist via COM und wäre in VBA direkt sicher schneller.
    Daher kommt es ein bissl drauf an wie oft du auf Zellen/Ranges etc. zugreifst.
    Das ist meine Signatur und sie wird wunderbar sein!

    Mono schrieb:

    Hi,

    erstmal noch zu deinem Code oben.
    Die Copy Methode ist meiner Erfahrung nach nicht sehr performant. Du kannst stattdessen (wenn es dir nur um Werte geht) einfach beispielhaft Worksheet1.Range("A1:C19").Value = Worksheet2.Range("A1:C19").Value verwenden.
    Dann sollten auch Kommentare nicht kopiert werden.

    Zu deiner Frage mit VSTO vs VBA kommt es drauf an. VSTO ist generell vll etwas schneller, solange du nicht auf Excel zugreifst.
    Der Zugriff ist via COM und wäre in VBA direkt sicher schneller.
    Daher kommt es ein bissl drauf an wie oft du auf Zellen/Ranges etc. zugreifst.


    Das Problem bei der Sache ist, das ich die Range nicht immer genau sagen kann.
    Mit den Werten aus dem Array wird in einer Tabelle in einer Spalte der Filter gefüttert. Dann werden bestimmte Spalten vom Filterergebniss in ein neues Arbeitsblatt kopiert. Mit diesen Daten werden dann in zwei "Data-Tabellen" Werte verglichen und berechnungen angestellt. Wenn das alles durch ist, wird das Blatt geleert und der nächste Wert wird in den Filter geschoben.

    Okay, da ich in diesem Fall schon viel auf Zellen oder generell Excel zugreife, bleibe ich erstmal bei VBA.
    Vielleicht bekomme ich ja eine Eingebung wie ich das alles innerhalb von Variabeln bzw Arrays oder so laufen lassen kann. Dann wäre glaube ich VSTO schon eine alternative.

    Mit VSTO erstelle ich ja Add-Ins. Kann ich diese auch innerhalb der Mappe speichern wie die Makros oder geht das nicht?
    Hab erst gestern Abend angefangen mich über VSTO schlau zu machen. Jemand paar Tipps wo man gute Unterlagen bekommt zum lernen/Üben?
    Ich muss hier das Thema nochmal benutzen :D

    VB.NET-Quellcode

    1. Dim arr() As String 'Array
    2. Dim Counter As Long 'Zähler für das Array
    3. Dim strSpeicher As String 'Zwischenspeicher
    4. Counter = 0
    5. For i = 2 To rngEnde
    6. strSpeicher = wsProjekt.Cells(i, 3).Value
    7. arr(Counter) = strSpeicher
    8. Counter = Counter + 1
    9. ReDim Preserve arr(Counter)
    10. strSpeicher = ""
    11. Next


    rngEnde ist als Long deklariert.

    Das ist mein Code um Werte aus bestimmten Zellen, beginnend bei C2, C3 usw.
    Bei der anderen Tabelle funktioniert das, aber hier haut der mit in Zeile 9 den "Laufzeitfehler 9 - Index außerhalb des gültigen Bereichs" um die Ohren.
    Ich finde den Fehler nicht. Ich habe die For-Schleife gleich aufgebaut wie bei einem funktionierenden Array.

    Sieht jemand auf anhieb den Fehler? Danke :)
    Du solltest wohl für arr erstmal mithilfe von ReDim eine Größe festlegen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.