Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1672to1676
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Performance-Problem mit Array lösen?

Performance-Problem mit Array lösen?
08.02.2019 08:42:52
Sven
Hallo Profis,
ich benötige bitte Eure Unterstützung:
Ich haben einen VBA-Code der mir tgl. die Arbeit erleichtert und recht großen händigen Aufwand in meiner Abteilung reduziert.
Problem hierbei ist eine neu eingebaute Aufbereitung der Daten, welche ca. 5 Minuten dauert. Die Performance ist für mich inakzebtabel!!!
Syntax:
Ich durchlaufe mit For-Schleife ein Tabellenblatt mit vielen Zeilen.
Wenn die Zeile (bzw. eine einzelne Zelle in der Zeile) eine bestimmte Bedingung erfüllt, kopiere ich diese Zeile in eine zweite Tabelle (letzte beschrieben Zeile +1) und starte eine zweite For-Schleife, welche diese Zeile solange untereinander dupiziert bis eine zweite Bedingung nicht mehr erfüllt ist.
Dabei wird eine Zelle der letzten Spalte um den Wert 1 erhöht.
Ich arbeite beim bearbeiten von Tabellen in der Regel mit Arrays, da diese natürlich wesentlich performanter sind, bei der oben beschrieben Logik stoße ich jedoch an die Grenze meiner Kenntnisse. Basics wie das vermeiden von "Select" usw. wurden natürlich schon berücksichtigt! :-)
Ich hatte den Plan die erste Tabelle in "arr1", dann daraus "arr2" dynamisch aufbauen. Wahrscheinlich funktioniert dies mit der dynamischen dimensionierung über "Redim" nicht. :-(
Hat jemand eine guten Vorschlag, wie die ohne Kopie/Paste direkt in den Tabellen umsetzen kann?
Im Anhang eine Stark vereinfachte Darstellung mit Vorher und Nachher.
https://www.herber.de/bbs/user/127502.xlsx
Bitte um Eure Hilfe.
Vielen Dank vorab. :-)

6
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Performance-Problem mit Array lösen?
08.02.2019 09:56:32
Daniel
Hi
die Innere Schleife kannst du dir sparen, wenn du beim Einfügen als Ziel nicht nur die linke obere Zelle angibst, sondern den gesamten Bereich der ausgefüllt werden soll. Excel dupliziert dann beim Einfügen die Zellen entsprechend.
dh mit Rows(1).Copy Destination:=Rows(2).Resize(10) wird die Zeile 1 beim einfügen 10x dupliziert.
die fortlaufenden Nummern in Spalte 2 und Spalte 7 kannst du dann mit Inhalte ausfüllen - Reihe in einem Schritt erzeugen.
sieht als Code dann so aus:
Sub test()
Dim Zelle As Range
With Sheets("Tabelle2")
.Cells.Clear
Sheets("Tabelle1").Rows(1).Copy .Cells(1, 1)
For Each Zelle In Sheets("Tabelle1").Columns(1).SpecialCells(xlCellTypeConstants, 2)
If Zelle.Value = "kopieren" Then
Zelle.Resize(, 7).Copy
With .Cells(.Rows.Count, 1).End(xlUp).Offset(1, 0) _
.Resize(Zelle.Offset(0, 1).Value + 1, 7)
.PasteSpecial xlPasteAll
.Columns(2).DataSeries Rowcol:=xlColumns, Type:=xlLinear, Step:=-1
.Columns(7).DataSeries Rowcol:=xlColumns, Type:=xlLinear, Step:=1
End With
End If
Next
End With
End Sub

beim Arbeiten mit Arrays muss man beachten, dass ein Redim Preseve (redim mit erhalt der Inhalte) nur mit der jeweils letzten Dimension funktioniert.
in deinem Fall wäre es aber durchaus möglich, das Ergebnisarray schon vorab auf die richtige Größe zu dimensionieren, weil du ja einfach nur die Werte aus Spalte 2 bei denen "kopieren" steht, addieren (dazu gibt's ja SummeWenn bzw Worksheetfunction.SumIf in VBA) und dann nochmal die Anzahl selbst hinzufügen musst.
Gruß Daniel
Anzeige
AW: Performance-Problem mit Array lösen?
08.02.2019 13:12:13
Sven
Hallo Daniel,
ich bin mehr als beeindruckt wie schnell hier eine so kompetente Antwort erscheint.
Der Code funktioniert im Beispile super! Ich werde diesen übers Wochenende an meinen Code anpassen und die Performance testen.
Vielen Dank schon mal. Echt Klasse! :-)
AW: Performance-Problem mit Array lösen?
08.02.2019 13:59:47
Nepumuk
Hallo Sven,
hier eine reine Array-Lösung:
Option Explicit

Public Sub CopyFill()
    
    Const COPY_CRITERIA As String = "kopieren" ' Anpassen !!!
    
    Dim avntInput As Variant, avntOutput() As Variant
    Dim ialngInputIndex1 As Long, ialngInputIndex2 As Long
    Dim ialngOuputIndex1 As Long, ialngOuputIndex2 As Long
    Dim lngPlusCounter As Long, lngMinusCounter As Long
    
    With Worksheets("Tabelle1") ' Anpassen !!!
        avntInput = .Range(.Cells(2, 1), .Cells(.Rows.Count, 7).End(xlUp)).Value
    End With
    
    ialngOuputIndex1 = 1
    
    For ialngInputIndex1 = 1 To UBound(avntInput, 1)
        
        If avntInput(ialngInputIndex1, 1) = COPY_CRITERIA Then
            
            lngMinusCounter = avntInput(ialngInputIndex1, 2)
            lngPlusCounter = 1
            
            Redim Preserve avntOutput(1 To 7, 1 To ialngOuputIndex1 + lngMinusCounter)
            
            For ialngInputIndex2 = 1 To lngMinusCounter + 1
                
                For ialngOuputIndex2 = 1 To 6
                    
                    avntOutput(ialngOuputIndex2, ialngOuputIndex1) = _
                        avntInput(ialngInputIndex1, ialngOuputIndex2)
                    
                Next
                
                avntOutput(2, ialngOuputIndex1) = lngMinusCounter
                avntOutput(7, ialngOuputIndex1) = lngPlusCounter
                
                lngMinusCounter = lngMinusCounter - 1
                lngPlusCounter = lngPlusCounter + 1
                ialngOuputIndex1 = ialngOuputIndex1 + 1
                
            Next
        End If
    Next
    
    With Worksheets("Tabelle2") ' Anpassen !!!
        .Cells(.Rows.Count, 1).End(xlUp).Offset(1, 0).Resize( _
            UBound(avntOutput, 2), 7) = Application.Transpose(avntOutput)
    End With
    
End Sub

Gruß
Nepumuk
Anzeige
warum hier nicht gleich die benötige Arraygröße
08.02.2019 14:11:35
Daniel
bestimmen und sich dann das Redim-Preserve und vorallem das Worksheetfunction.Transpose einsparen?
Gruß Daniel
AW: warum hier nicht gleich die benötige Arraygröße
08.02.2019 14:27:13
Nepumuk
Hallo,
um damit das Array 2mal durchlaufen? Macht für mich keinen Sinn.
Gruß
Nepumuk
AW: warum hier nicht gleich die benötige Arraygröße
08.02.2019 14:52:47
Daniel
Hi
lieber eine Schleife über alle Zeilen des kompakten Arrays (Worksheetfunction.SumIf), als eine Schleife über alle Elemente (Zeilen x Spalten) des "großen" Ergebnisarrays! (Worksheetfunction.Transpose)
btw Worksheetfunction.Transpose ist langsamer, als wenn du das Array per selber programmierter geschachtelter Schleife transponierst und hast zudem noch eine Limitierung in der Anzahl der Elemente!
Gruß Daniel
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige