Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1412to1416
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

Verbesserung VBA Code

Verbesserung VBA Code
19.03.2015 15:09:11
Plagiat1312
Hallo!
Heute habe ich AdHoc einen Code geschrieben der mir wohl doch etwas Arbeit abgenommen hat, da der vorliegende Fall für den Upload ins BW vorgesehen war und > 100.000 Zeilen hatte. Und Wahrscheinlich ändern sich die ein oder anderen Dateien noch einmal.
Beim schreiben ist mir aber aufgefallen, dass ich das ganze wirklich sehr eigenartig ( wenn auch immerhin schnell) gelöst habe.
die Aufgabe war:
Kopiere die Spalten E und G von Zeile 5 bis Zeile X (idealerweise zu ermitteln) und dann anschließend dazu immer eine weitere Spalte ab der Spalte K und gebe diese 3 Spalten dann untereinander in einer neuem Tabellenblatt aus.
Der Code funktioniert nur frage Ich mich doch ernsthaft ob es nicht deutlich bessere Lösungen gibt, gegebenenfalls über ein Array.
Danke jetzt schon demjenigen der sich die Mühe macht da Hirnschmalz reinzustecken, Ich bin auf jedenfall interessiert daran mich hier selbst zu verbessern!
Schönen Gruß
Plagiat1312
mein Code war:

Option Explicit
Option Base 1
Sub Extraktion()
Dim LngAnzahlZeilen As Long, LngAnzahlSpalten As Long, LngAnzahlZeilen2 As Long, i As Long
Dim wbphasing As Worksheet
Dim wbCOPA As Worksheet
Set wbphasing = ThisWorkbook.Worksheets("PhasingDaten")
Set wbCOPA = ThisWorkbook.Worksheets("COPA")
With wbphasing
LngAnzahlZeilen = IIf(IsEmpty(.Cells(Rows.Count, 6)), .Cells(Rows.Count, 6).End(xlUp).Row, . _
Rows.Count)
LngAnzahlSpalten = IIf(IsEmpty(.Cells(6, Columns.Count)), .Cells(6, Columns.Count).End(xlToLeft) _
_
.Column, .Columns.Count)
End With
For i = 11 To LngAnzahlSpalten
With wbphasing
.Range("E5:G" & LngAnzahlZeilen).Copy
End With
With wbCOPA
LngAnzahlZeilen2 = IIf(IsEmpty(.Cells(Rows.Count, 1)), .Cells(Rows.Count, 1).End(xlUp).Row,  _
_
.Rows.Count)
.Range("A" & LngAnzahlZeilen2 + 1).PasteSpecial (xlPasteValues)
End With
With wbphasing
.Range(.Cells(5, i), .Cells(LngAnzahlZeilen, i)).Copy
End With
With wbCOPA
.Range("D" & LngAnzahlZeilen2 + 1).PasteSpecial (xlPasteValues)
End With
With wbphasing
.Cells(5, i).Copy
End With
With wbCOPA
.Range(.Cells(LngAnzahlZeilen2 + 1, 5), .Cells(LngAnzahlZeilen2 + 912, 5)).PasteSpecial ( _
xlPasteValues)
LngAnzahlZeilen2 = IIf(IsEmpty(.Cells(Rows.Count, 1)), .Cells(Rows.Count, 1).End(xlUp).Row, . _
Rows.Count)
End With
Next i
End Sub

2
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Verbesserung VBA Code
20.03.2015 12:52:37
fcs
Hallo Plagiat1312,
vieles ist natürlich Ansichtsache.
Wichtig ist hier vorübergehend die Bildschirmaktualisierung zu deaktivieren und den Berechnungsmodus auf manuell zu setzen, um die Ausführungsgeschwindigkeit zu erhöhen.
Programmierstil: Gleichartige Berechnungen -hier letzte Zeile oder letzte Spalte ermitteln- sollte man in eine Function auslagern, wenn es etwa mehr Code-Text ist, das macht den Hauptcode etwas übersichtlicher.
Bei der Angeabe von Zellbereichen bevorzuge ich die
.Range(.cells(5,4),.cells(Zeile2,6)) statt .Range("A5:G" & Zeile2)
weil es bei der Programmierung flexibler ist und in der Makroausführung geringfüg schneller ist.
Nachfolgend mein Vorschlag für dein Makro.
Ob die Variante via Arrays Geschwindigkeitsvorteile bringt? Bei meinen wenigen Testdaten konnte ich kaum einen Unterschied feststellen.
Gruß
Franz
Option Explicit
Option Base 1
Sub Extraktion()
Dim LngAnzahlZeilen As Long, LngAnzahlSpalten As Long, LngAnzahlZeilen2 As Long
Dim StatusCalc As Long, i As Long
Dim wbphasing As Worksheet
Dim wbCOPA As Worksheet
Dim rngZeilenTitel As Range
Set wbphasing = ThisWorkbook.Worksheets("PhasingDaten")
Set wbCOPA = ThisWorkbook.Worksheets("COPA")
'in Blatt "PhasingDaten"
With wbphasing
'letzte Zeile mit Inhalt in Spalte F
LngAnzahlZeilen = fncLastRow(Spalte:=6, wks:=wbphasing)
'letzte Spalte mit Inhalt in Zeile 6
LngAnzahlSpalten = fncLastColumn(Zeile:=6, wks:=wbphasing)
'Zellbereich mit zu kopierenden Zeilentiteln setzen
Set rngZeilenTitel = .Range("E5:G" & LngAnzahlZeilen)
End With
With wbCOPA
'1. Einfügezeile in Blatt COPA
LngAnzahlZeilen2 = fncLastRow(Spalte:=1, wks:=wbCOPA) + 1
End With
'Makrobremsen lösen
With Application
.ScreenUpdating = False
StatusCalc = .Calculation
.Calculation = xlCalculationManual
End With
For i = 11 To LngAnzahlSpalten
rngZeilenTitel.Copy
With wbCOPA
.Cells(LngAnzahlZeilen2, 1).PasteSpecial xlPasteValues
End With
With wbphasing
.Range(.Cells(5, i), .Cells(LngAnzahlZeilen, i)).Copy
End With
With wbCOPA
.Cells(LngAnzahlZeilen2, 4).PasteSpecial xlPasteValues
End With
With wbCOPA
.Range(.Cells(LngAnzahlZeilen2, 5), _
.Cells(LngAnzahlZeilen2 + rngZeilenTitel.Rows.Count - 1, 5)) _
.Value = wbphasing.Cells(5, i).Value
End With
LngAnzahlZeilen2 = LngAnzahlZeilen2 + rngZeilenTitel.Rows.Count
Next i
'Makrobremsen zurücksetzen
With Application
.ScreenUpdating = True
.Calculation = StatusCalc
End With
End Sub
Public Function fncLastRow(Spalte As Long, Optional wks As Worksheet)
'letzte Zeile mit Inhalt in Spalte
If wks Is Nothing Then Set wks = ActiveSheet
With wks
fncLastRow = IIf(IsEmpty(.Cells(.Rows.Count, Spalte)), _
.Cells(.Rows.Count, Spalte).End(xlUp).Row, .Rows.Count)
End With
End Function
Public Function fncLastColumn(Zeile As Long, Optional wks As Worksheet)
'letzte Spalte mit Inhalt in Zeile
If wks Is Nothing Then Set wks = ActiveSheet
With wks
fncLastColumn = IIf(IsEmpty(.Cells(Zeile, .Columns.Count)), _
.Cells(Zeile, .Columns.Count).End(xlToLeft).Column, .Columns.Count)
End With
End Function
Sub Extraktion_Array()
Dim LngAnzahlZeilen As Long, LngAnzahlSpalten As Long, LngAnzahlZeilen2 As Long
Dim StatusCalc As Long, i As Long, Zeile As Long, Zeile_Z As Long
Dim wbphasing As Worksheet
Dim wbCOPA As Worksheet
Dim arrData
Dim arrZiel
Set wbphasing = ThisWorkbook.Worksheets("PhasingDaten")
Set wbCOPA = ThisWorkbook.Worksheets("COPA")
'in Blatt "PhasingDaten"
With wbphasing
'letzte Zeile mit Inhalt in Spalte F
LngAnzahlZeilen = fncLastRow(Spalte:=6, wks:=wbphasing)
'letzte Spalte mit Inhalt in Zeile 6
LngAnzahlSpalten = fncLastColumn(Zeile:=6, wks:=wbphasing)
'Daten in Array einlesen
arrData = .Range(.Cells(5, 1), .Cells(LngAnzahlZeilen, LngAnzahlSpalten))
'Array für Ergebnisdaten dimensionieren
ReDim arrZiel(1 To UBound(arrData, 1) * (LngAnzahlSpalten - 11 + 1), 1 To 5)
End With
'Daten in das Ergebnisarray übertragen
Zeile_Z = 0
For i = 11 To LngAnzahlSpalten
For Zeile = 1 To UBound(arrData, 1)
Zeile_Z = Zeile_Z + 1
arrZiel(Zeile_Z, 1) = arrData(Zeile, 5) 'Zeilen-Titel aus E
arrZiel(Zeile_Z, 2) = arrData(Zeile, 6) 'Zeilen-Titel aus E
arrZiel(Zeile_Z, 3) = arrData(Zeile, 7) 'Zeilen-Titel aus E
arrZiel(Zeile_Z, 4) = arrData(Zeile, i) 'Wert in Zeile aus Spalte
arrZiel(Zeile_Z, 5) = arrData(1, i) 'Wert aus 1. Zeile in Spalte
Next
Next i
'Makrobremsen lösen
With Application
.ScreenUpdating = False
StatusCalc = .Calculation
.Calculation = xlCalculationManual
End With
With wbCOPA
'1. Einfügezeile in Blatt COPA
LngAnzahlZeilen2 = fncLastRow(Spalte:=1, wks:=wbCOPA) + 1
'Daten aus Ergebnis-Array einfügen
.Cells(LngAnzahlZeilen2, 1).Resize(UBound(arrZiel, 1), UBound(arrZiel, 2)) _
.Value = arrZiel
End With
'Daten-Arrays leeren
Erase arrData, arrZiel
'Makrobremsen zurücksetzen
With Application
.ScreenUpdating = True
.Calculation = StatusCalc
End With
End Sub

Anzeige
AW: Verbesserung VBA Code
20.03.2015 13:01:39
Plagiat1312
Hallo fcs,
Danke vorab für deine Mühe! Die Performance steht hier glücklicherweise absolut nicht im Vordergrund. Selbst bei größer 100.000 Zeilen hat mich das ganze nur wenige Sekunden gekostet.
Es ging mir nur darum einen eleganteren Weg zu finden um Programmierzeit, Fehleranfälligkeit und gaaaanz ganz hinten auch um die Performance zu verbessern.
Werde mir deine Array Version einmal anschauen. Danke nochmals!
Gruß
Plagiat1312

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige