Live-Forum - Die aktuellen Beiträge
Datum
Titel
24.04.2024 19:29:30
24.04.2024 18:49:56
Anzeige
Archiv - Navigation
1776to1780
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

VBA code schneller machen

VBA code schneller machen
27.08.2020 11:04:23
Jimmy
Hallo liebes Excel Forum,
Erstmal vorab, ich bin absolut neu in Excel VBA. Ich habe einen VBA Code für einen Urlaubsplaner geschrieben. Er vergleicht zunächst von Mappe (Abwesenheit) und der Mappe (Übersicht) die MA's miteinander und falls sie übereinstimmen geht der Loop anschließend über das jeweilige Datum des MA's und markiert die Datumsfelder farblich je nach Art der Abwesenheit.
Das Problem ist, dass dieses Makro sehr langsam ist. Ich vermute stark das es an den For-Each Schleifen liegt. Hat jemand eine Idee wie man den Code schneller machen kann?
Vielen Dank für jegliche Hilfe!

Sub FarblicheMarkierung()
Dim c As Range
Dim e As Range
Dim datum_zeile As Variant
Dim zelle As Integer
Dim bereich1 As Variant
Dim bereich2 As Variant
Dim bereich3 As Variant
Dim bereich4 As Variant
Dim bereich5 As Variant
Dim bereich6 As Variant
Dim bereich7 As Variant
Dim bereich8 As Variant
Dim bereich9 As Variant
Dim zeile_urlaub As Integer
Dim datum_von As Variant
Dim datum_bis As Variant
Dim Art_Abwesenheit As Variant
Dim ButtonAntwort As Long
Dim size1 As Integer
Dim size2 As Integer
bereich1 = "D"
bereich2 = "E"
bereich3 = "G"
bereich4 = "NG"
bereich5 = "F"
bereich6 = "C"
bereich7 = "C4"
bereich8 = "B"
bereich9 = "B4"
size1 = WorksheetFunction.CountA(Worksheets("Abwesenheit").Columns(3)) + 1
size2 = WorksheetFunction.CountA(Worksheets("Übersicht").Columns(2)) + 2
Range("G4:NG264").Cells.Interior.Color = RGB(230, 230, 230)
For Each c In Worksheets("Abwesenheit").Range(bereich7, bereich6 & size1).Cells
For Each e In Worksheets("Übersicht").Range(bereich9, bereich8 & size2).Cells
If c.Text = e.Text Then
zelle = e.Row
zeile_urlaub = c.Row
datum_von = Sheets("Abwesenheit").Range(bereich1 & zeile_urlaub)
datum_bis = Sheets("Abwesenheit").Range(bereich2 & zeile_urlaub)
Art_Abwesenheit = Sheets("Abwesenheit").Range(bereich5 & zeile_urlaub)
For Each datum_zeile In Worksheets("Übersicht").Range(bereich3 & zelle, bereich4 &   _
_
_
_
zelle).Cells
If datum_zeile >= datum_von And datum_zeile 

Problem:
-> Makro ist sehr langsam

8
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: VBA code schneller machen
27.08.2020 11:32:17
Daniel
Hi
mal an den Details fummeln:
1. wenn ArtAbwesenheit = "Urlaub" ist, sind die beiden anderen Prüfungen ja nicht mehr notwendig.
dein Konstrukt mit unabhängigen IFs führt diese aber immer durch.
Stelle hier um auf IF THEN - ELSEIF oder SELECT CASE
2. IF Bedingung1 AND Bedingung2 ist langsamer als zwei geschachtelte IFs:
If Bedinung1 THEN
If Bedinung2 THEN
3. "DatumZeile" ist bei dir ein Zellbereich.
du verwendest aber sehr oft nur den Wert aus diesem Zellbereich.
lies daher in der Schleife den Wert in eine eigene Wertvariable ein und verwende diese, wenn du den Wert brauchst und "DatumZeile", wenn du auf das Zellobjekt zugreifen willst (umfärben).
Der Zugriff auf die Wertvariable ist schneller, als jedesmal über das Rangeobjekt den Wert auszulesen.
ansonsten müsste man mal schauen, ob sich das mit der geschachtelten Schleife nicht irgendiwe intelligenter lösen lösst, aber dafür kenne ich deine Aufgabenstellung noch Zuwenig.
Gruß Daniel
Anzeige
AW: VBA code schneller machen
27.08.2020 14:13:47
Jimmy
Vielen Dank für die ausführliche Antwort.
Ich habe den Code gemäß deinen Vorschlägen 1 & 2 überarbeitet zu:
[..]

For Each datum_zeile In Worksheets("Übersicht").Range(bereich3 & zelle, bereich4 & zelle).Cells
If datum_zeile >= datum_von Then
If datum_zeile 

[..]
Der Code ist damit schneller geworden.
Bei dem Vorschlag Nr. 3 habe ich leider nicht ganz verstanden wie du das meinst.
"wenn du den Wert brauchst und 'DatumZeile', wenn du auf das Zellobjekt zugreifen willst (umfärben)." Ist damit gemeint den Zellwert sowie die Range in ein Array einzugeben?
LG,
Jimmy
Anzeige
AW: VBA code schneller machen
27.08.2020 14:23:26
Daniel
hi
kann man mit Array machen, ist hier aber nicht sinnvoll, da du ja auch die Zelle brauchst um sie zu färben.
gemeint war das in etwa so:
dim Datum_Zeile_Wert as (gleicher Typ wie datum_von)
For Each datum_zeile In Worksheets("Übersicht").Range(bereich3 & zelle, bereich4 & zelle).Cells
Datum_Zeile_Wert = Datum_zeile.value
If dDatum_Zeile_Wert >= datum_von Then
If Datum_Zeile_Wert 
Gruß Daniel
AW: VBA code schneller machen
27.08.2020 13:18:17
fcs
Hallo Jimmy,
ich hab in deinem Makro einige Anpassungen und Ergänzungen gemacht.
1. Einstellungen (Makrobremsen) werden vorübergehend angepasst
2. Anzahl der Berechnungen/Prüfungen reduziert
a) Füllfarbe wird vor der For-Next-Schleife berechnet
b) Die Spalte mit dem Datum_von wird berechnet
c) Die For-Next-Schleife, die die Zellen färbt, startet in der Spalte mit dem Datum_von und verlässt die Schleife, wenn das Datum_bis überschritten wird.
Ich hoffe, dass die Zeile
              spaVon = Application.Match(CDbl(datum_von), .Cells, 0) + .Column - 1

Funktioniert, denn die Funktion VERGLEICH (MATCH) bereitet mit Datumswerten gelegentlich Probleme.
LG
Franz
Sub FarblicheMarkierung()
Dim c As Range
Dim e As Range
Dim datum_zeile As Variant
Dim zelle As Integer
Dim bereich1 As Variant
Dim bereich2 As Variant
Dim bereich3 As Variant
Dim bereich4 As Variant
Dim bereich5 As Variant
Dim bereich6 As Variant
Dim bereich7 As Variant
Dim bereich8 As Variant
Dim bereich9 As Variant
Dim zeile_urlaub As Integer
Dim datum_von As Variant
Dim datum_bis As Variant
Dim Art_Abwesenheit As Variant
Dim ButtonAntwort As Long
Dim size1 As Integer
Dim size2 As Integer
Dim lngColorIndex As Long
Dim StatusCalc As Long
Dim spaVon As Variant
bereich1 = "D"
bereich2 = "E"
bereich3 = "G"
bereich4 = "NG"
bereich5 = "F"
bereich6 = "C"
bereich7 = "C4"
bereich8 = "B"
bereich9 = "B4"
size1 = WorksheetFunction.CountA(Worksheets("Abwesenheit").Columns(3)) + 1
size2 = WorksheetFunction.CountA(Worksheets("Übersicht").Columns(2)) + 2
'Makrobremsen lösen
With Application
.ScreenUpdating = False
StatusCalc = .Calculation
.Calculation = xlCalculationManual
.EnableEvents = False
End With
Range("G4:NG264").Cells.Interior.Color = RGB(230, 230, 230)
For Each c In Worksheets("Abwesenheit").Range(bereich7, bereich6 & size1).Cells
For Each e In Worksheets("Übersicht").Range(bereich9, bereich8 & size2).Cells
If c.Text = e.Text Then
zelle = e.Row
zeile_urlaub = c.Row
datum_von = Sheets("Abwesenheit").Range(bereich1 & zeile_urlaub)
datum_bis = Sheets("Abwesenheit").Range(bereich2 & zeile_urlaub)
Art_Abwesenheit = Sheets("Abwesenheit").Range(bereich5 & zeile_urlaub)
'Füllfarbe berechnen
Select Case Art_Abwesenheit
Case "Urlaub":              lngColorIndex = 3
Case "Freizeitausgleich":   lngColorIndex = 4
Case "Bildungsurlaub":      lngColorIndex = 5
End Select
'Spalte mit Datum_von  berechnen
With Worksheets("Übersicht").Range(bereich3 & zelle, bereich4 & zelle)
spaVon = Application.Match(CDbl(datum_von), .Cells, 0) + .Column - 1
End With
spaVon = Worksheets("Übersicht").Columns(spaVon).Address(False, False, xlA1)
spaVon = Left(spaVon, InStr(1, spaVon, ":") - 1)
For Each datum_zeile In Worksheets("Übersicht").Range(spaVon & zelle, _
bereich4 & zelle).Cells
Select Case datum_zeile
Case datum_von To datum_bis
datum_zeile.Interior.ColorIndex = lngColorIndex
Case Is > datum_bis
Exit For
End Select
Next datum_zeile
End If
Next e
Next c
'Makrobremsen zurücksetzen
With Application
.ScreenUpdating = True
.Calculation = StatusCalc
.EnableEvents = True
End With
End Sub

Anzeige
AW: VBA code schneller machen
27.08.2020 13:52:47
Jimmy
Vielen Dank für die gute und ausführliche Antwort.
Leider macht nun, wie von dir schon vorhergesagt genau diese besagte Zeile Probleme.
Ich bekomme als Fehlermeldung: Laufzeitfehler '13': Typen unverträglich zurück.
Gibt es eventuell eine Alternative mit der ich diesen Fehler umgehen kann?
LG,
Jimmy
AW: VBA code schneller machen
27.08.2020 14:18:19
Daniel
Hi
bei solchen Kalendern stehen die Datumwerte in der Regel aufsteigend sortiert und lückenlos.
dann muss man einzelne Datumswerte nicht suchen, sondern kann die Spaltennummer einfach nach folgendem Schema berechnen:
Spalte des gesuchten Datums = erste Spalte des Kalenders + gesuchtes Datum - erstes Datum des Kalernders
das geht so einfach, weil für Excel ein Datum eine normale Zahl ist, ein Tag entspricht dem Wert 1
Gruß Daniel
Anzeige
AW: VBA code schneller machen
27.08.2020 17:36:00
fcs
Hallo Jimmy,
Daniels Vorschlag umgesetzt sollte hier so aussehen:
            'Spalte mit Datum_von  berechnen
With Worksheets("Übersicht").Range(bereich3 & zelle, bereich4 & zelle)
spaVon = .Column + datum_von - .Range("A1").Value
End With
spaVon = Worksheets("Übersicht").Columns(spaVon).Address(False, False, xlA1)
spaVon = Left(spaVon, InStr(1, spaVon, ":") - 1)

LG
Franz
AW: VBA code schneller machen
27.08.2020 19:10:46
onur
So wie ich das sehe, brauchst du gar kein Makro, sondern nur 3 bedingte Formatierungen.

17 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige