Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Redim-Problem

Forumthread: Redim-Problem

Redim-Problem
22.06.2023 12:19:04
Herbert_Grom

Hallo,

leider stehe ich hier voll auf dem Schlauch mit meiner Redim-Anweisung. Vielleicht seht ihr das Problem, warum er mir bei der gelben Zeile diese Fehlermeldung bringt? Vielen Dank im Voraus.

Sub DatenSammeln()
   Dim lSheetsCount&, lRowsCount&, lLastRow&, ArrSammler(), lArrCounter&
   
   lArrCounter = 0
   
   ReDim Preserve ArrSammler(0 To lArrCounter, 0 To 4)
   
   For lSheetsCount = 4 To Sheets.Count
      With Sheets(lSheetsCount)
         If .Cells(3, "A") = "" Then Exit For
         lLastRow = .Cells(Rows.Count, "A").End(xlUp).Row
         For lRowsCount = 3 To lLastRow
            If .Cells(lRowsCount, "G") = "xxx" Or .Cells(lRowsCount, "G") = "yyy" Then
               ArrSammler(lArrCounter, 0) = .Name                    
               ArrSammler(lArrCounter, 1) = .Cells(lRowsCount, "B")  
               ArrSammler(lArrCounter, 2) = .Cells(1, "A")           
               ArrSammler(lArrCounter, 3) = .Cells(lRowsCount, "G")  
               ArrSammler(lArrCounter, 4) = .Cells(lRowsCount, "H")   
               lArrCounter = lArrCounter + 1
               ReDim Preserve ArrSammler(0 To lArrCounter, 0 To 4)
            End If
         Next lRowsCount
      End With
   Next lSheetsCount
   ReDim Preserve ArrSammler(0 To lArrCounter - 1, 0 To 4)
End Sub


Userbild

Servus

Anzeige

17
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Redim-Problem
22.06.2023 12:40:30
Daniel
Hi
du kannst mit ReDim immer nur die letzte Dimension verändern, also die Spalten.
die restlichen Dimensionen müssen konstant bleiben.
Das Problem ist, dass VBA intern auch das zweidimensionale Array linear speichert, also in ein eindimensionales Array umwandelt, und dabei eine bestimmte Struktur bei der Zeilen/Spaltenzuordnung einhält (also quasi so, wie wenn du Schiffer-versenken auf einem Zollstock spielst)
Spalten kann man relativ einfach hinzufügen, wolltest du aber zusätzliche Zeilen haben, müsstest du alle Werte dann auf neue Postionen schieben, daher macht VBA das nicht.

um das Problem zu lösen, gibt es zwei Ansätze:
a) man bestimmt vorher, wie viele Zeilen das Array benötigen wird und Dimensioniert das Array gleich passend (du musst ja nur mit Worksheetfunction.Countif zählen, wie oft deine geschwärzten suchbegriffe vorkommen)
b) du tauschst im Array Zeilen und Spalten, also
ArrSammler(0, lArrCounter) = .Name , so dass die zweite Dimension die variable ist und nicht die erste. Am schluss kann man das Array mit Worksheetfunction.Transpose wieder in die gewünschte Ausrichtung bringen.

Variante a) wäre immer vorzuziehen und b) nur dann anzuwenden, wenn es nicht oder nur mit erheblichen Aufwand möglich ist, die Notwendige Dimensionierung vorab zu bestimmen.

Gruß Daniel


Anzeige
AW: Redim-Problem
22.06.2023 13:03:54
Herbert_Grom
Hallo Daniel,

vielen Dank für deine Infos. Hätte ich deine Nachricht doch mal nur zuerst gelesen, dann hätte ich mir meine Frage an Nepumuk sparen können, denn du hast es super erklärt.

Servus


AW: Redim-Problem
22.06.2023 12:43:20
Nepumuk
Hallo Herbert,

mit Redim kannst du nur die letzte Dimension ändern. Kipp dein Array um 90° :

Sub DatenSammeln()
    Dim lSheetsCount&, lRowsCount&, lLastRow&, ArrSammler(), lArrCounter&
   
    lArrCounter = 0

    For lSheetsCount = 4 To Sheets.Count
        With Sheets(lSheetsCount)
            If .Cells(3, "A") = "" Then Exit For
            lLastRow = .Cells(Rows.Count, "A").End(xlUp).Row
            For lRowsCount = 3 To lLastRow
                If .Cells(lRowsCount, "G") = "xxx" Or .Cells(lRowsCount, "G") = "yyy" Then

                    ReDim Preserve ArrSammler(0 To 4, lArrCounter)
   
                    ArrSammler(0, lArrCounter) = .Name
                    ArrSammler(1, lArrCounter) = .Cells(lRowsCount, "B")
                    ArrSammler(2, lArrCounter) = .Cells(1, "A")
                    ArrSammler(3, lArrCounter) = .Cells(lRowsCount, "G")
                    ArrSammler(4, lArrCounter) = .Cells(lRowsCount, "H")
                    
                    lArrCounter = lArrCounter + 1

                End If
            Next lRowsCount
        End With
    Next lSheetsCount
End Sub
Zurückkippen geht dann mit:

Application.Transpose(ArrSammler)
Gruß
Nepumuk


Anzeige
AW: Redim-Problem
22.06.2023 13:01:33
Herbert_Grom
Hallo Nepumuk,

vielen Dank, das passt prima. Warum ich da Probleme hatte, ist das fehlende Verständnis dafür, warum ich das Array in diesem Falle um 90° kippen muss und damit die Spalten als erster Parameter angegeben werden müssen. Kannst du mir das bitte noch kurz erläutern?

Servus


Anzeige
AW: Redim-Problem
22.06.2023 13:04:56
Nepumuk
Hallo Herbert,

du kannst mit ReDim Preserve nur die letzte Dimension ändern.

Gruß
Nepumuk


AW: Redim-Problem
22.06.2023 13:08:57
Herbert_Grom
Hallo Nepumuk,

vielen Dank, jetzt habe ich es kapiert.

Servus


Anzeige
AW: Redim-Problem
22.06.2023 13:53:39
Rudi Maintaire
Hallo,
das ständige ReDim Preserve kannst du dir ersparen, indem du vor her ermittelst, wie viele xxx und yyy vorkommen und dann da Array von vorn herein richtig dimensionierst.

Gruß
Rudi


AW: Redim-Problem
22.06.2023 15:04:34
Herbert_Grom
Servus Rudi,

vielen Dank, das werde ich mal probieren.

Servus


Anzeige
AW: Redim-Problem
22.06.2023 19:49:51
Yal
Hallo Herbert,

leider wissen nicht, was mit dem Array anschliessend gemacht wird.
Im allgemein ist es abzuwägen, ob ein mehrdimensionale Array nötig ist. Hier könnte man durchaus einen 1-Dim Array verwenden.

Sub DatenSammeln()
Dim lSheetsCount As Long
Dim R As Long
Dim Arr()
Dim Msg As String

    Arr = Array() 'Dummy-Init, Ubound(Arr) ist -1
    
    For lSheetsCount = 4 To Sheets.Count
        With Sheets(lSheetsCount)
            If .Range("A3") = "" Then Exit For
            For R = 3 To .Cells(Rows.Count, "A").End(xlUp).Row
                If .Cells(R, "G") = "xxx" Or .Cells(R, "G") = "yyy" Then
                    Msg = .Name
                    Msg = Msg & "|" & .Cells(R, "B").Value
                    Msg = Msg & "|" & .Range("A1").Value
                    Msg = Msg & "|" & .Cells(R, "G")
                    Msg = Msg & "|" & .Cells(R, "H")
                    ReDim Preserve Arr(UBound(Arr) + 1)
                    Arr(UBound(Arr)) = Msg
                End If
            Next R
        End With
    Next lSheetsCount
End Sub
Anschliessend jede Eintrag mit Split (Arr(i), "|") auseinander zu nehmen.

VG
Yal


Anzeige
AW: Redim-Problem
23.06.2023 08:46:15
Herbert_Grom
Hallo Yal,

vielen Dank für deine Idee, aber ich benötige ein zweidimensionales Array.

Servus


AW: Redim-Problem
23.06.2023 09:49:37
Herbert_Grom
Hallo Yal,

ich habe deinen Vorschlag mal ausprobiert und er funktioniert natürlich prima, doch wie kriege ich den Inhalt auf 5 Spalten verteilt? Arrays sind einfach meine Achillesferse! ;o(=(

Servus


Anzeige
AW: Redim-Problem
23.06.2023 10:42:02
snb
Kein Redim Problem:

Sub M_snb()
  For Each it In Sheets
    If it.Index > 3 And it.Cells(3, 1) > "" Then
       sn = it.UsedRange
       For j = 3 To UBound(sn)
         If InStr("xxxyyy", sn(j, 7)) Then c00 = c00 & vbLf & sn(j, 2) & "|" & sn(1, 1) & "|" & sn(j, 7) & "|" & sn(j, 8)
       Next
     End If
   Next
   
  sn = Split(Mid(c00, 2), vbLf)
  For j = 0 To UBound(sn)
    sn(j) = Split(sn(j), "|")
  Next
End Sub
Minimiere interaktion mit dem Arbeitsblatt


Anzeige
AW: Redim-Problem
23.06.2023 11:35:55
Yal
Hallo Herbert,

zu deiner Frage, wie greife ich auf die im Array gelagerte Elemente:
die zweite Teil von snb's Code zeigt wie man den Split verwenden kann. Er benutzt sogar ein "doppelten" Split, weil er in einem String die beide Dimensionen vereint:
die 5 Elemente eine Zeile, getrennt durch "|"
alle Zeilen, je getrennt durch vbLf

Aus diese String "alles zusammen" erzeigt er zuerst einen ein-dimensionalen Array, in dem er nach vLf splittet:
sn = Split(Mid(c00, 2), vbLf)
Dann wird jede Element durch einen Array überschrieben:
  For j = 0 To UBound(sn)
    sn(j) = Split(sn(j), "|")
  Next
Das Ergebnis ist nicht ein zwei-Dim Array, sondern einen Array von Array. Die einzige unterschied ist, dass nicht mit sn(2, 3) sondern sn(2)(3) auf die dritte Spalte der zweite Zeile zugegriefen wird (da 0 der erste ist, 4te Spalte und 3te Zeile :-). Es funktioniert besonders gut, wenn die zweite Dimension (genauer gesagt die erste Dimension der Array in der Array) immer dieselbe Sizing hat. Sonst muss man mit LBound/UBound arbeiten.

VG
Yal


Anzeige
AW: Redim-Problem - Danke vielmals owt
23.06.2023 17:50:15
Herbert_Grom
,,,


AW: Redim-Problem
24.06.2023 10:00:22
Herbert_Grom
Hallo Yal,

vielen Dank für deine Erläuterungen. Ich habe jetzt das Makro von snb verwendet, in dem deine beiden Schnipsel vorhanden sind. Und doch steigt er in der u. a. Zeile aus mit der u. a. Fehlermeldung. Habe ich da noch etwas übersehen, oder falsch gemacht?

Userbild

Servus


Anzeige
AW: Redim-Problem
24.06.2023 14:46:05
Ulf

Sub M_snb()
    Dim sn As Variant
    Dim arrZeilen()
    Dim it As Sheet
    Dim j As Long
    Dim k As Long
    
    For Each it In Sheets
        If it.Index > 3 And it.Cells(3, 1) > "" Then
            sn = it.UsedRange
            ReDim arrZeilen(3, UBound(sn) - 3)
            For j = 3 To UBound(sn)
                If InStr("in Bearbeitung", sn(j, 7)) Then
                    arrZeilen(0, j - 3) = sn(j, 2)
                    arrZeilen(1, j - 3) = sn(1, 1)
                    arrZeilen(2, j - 3) = sn(j, 7)
                    arrZeilen(3, j - 3) = sn(j, 8)
                    'c00 = c00 & vbLf & sn(j, 2) & "|" & sn(1, 1) & "|" & sn(j, 7) & "|" & sn(j, 8)
                End If
            Next
        End If
    Next
'    sn = Split(Mid(c00, 2), vbLf)
'    For j = 0 To UBound(sn)
'        sn(j) = Split(sn(j), "|")
'    Next
    
    For j = 0 To UBound(arrZeilen, 2)
        For k = 0 To 3
            Debug.Print "Element " & j + 1 & " Stelle " & k & " " & arrZeilen(k, j)
        Next
    Next
End Sub

Anzeige
;

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige