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

Laufzeit - automatischer Aufruf von Subs

Laufzeit - automatischer Aufruf von Subs
21.02.2023 09:19:14
Subs
Hey zusammen,
Ich habe eher eine generelle Frage zu dem Aufruf von Subs aus einem anderen Sub heraus und der dadurch entstehenden Laufzeit.
Konkret geht es darum, dass ich zwei Subs habe, von denen eines zwingend als erstes ausgeführt werden muss, da mir dieses Sub die gegebene Liste sortiert und ich im zweiten Sub mit der sortierten Liste weiterarbeite.
Während ich programmiert habe, habe ich die Subs immer einzeln ausgeführt (Dauer war dann immer etwa 20Sek fürs sortieren und 10Sek fürs weiterarbeiten). Nun möchte ich am Anfang vom ersten Sub einfach kurz das zweite aufrufen, damit der Benutzer hinterher keine Reihenfolge beachten muss, sondern nur diesen einen Button klicken muss. Als ich das gerade gemacht habe, ist die Laufzeit aber plötzlich auf 75Sek hoch gegangen, was ich mir überhaupt nicht erklären kann.
Ich wollte deswegen einmal nachfragen, ob es da irgendwelche Tipps oder Tricks gibt, wenn man in einem Sub ein anderes aufruft.
Vielen Dank schonmal.
LG Finn64

10
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Laufzeit - automatischer Aufruf von Subs
21.02.2023 09:36:27
Subs
Hi
Zugegeben, schon ziemlich mysteriös. Generell finde ich 20 sec für eine Sortierung extrem lange. Wie viele Zeilen/Spalten hast du in etwa? Gibt es Formeln? Handelt es sich vielleicht um volatile Formeln https://www.tabellenexperte.de/excel-im-schneckentempo-volatile-funktionen/
Nur mal um zu testen, ob es einen spürbaren Unterschied macht:
Sub t()
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Call Makro1
Call Makro2
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
End Sub
Evtl. möchtest du die Makros auch mal zeigen. Vielleicht fällt etwas auf (z.B. mehrere Instanzen o.ä.), vielleicht auch nicht.
cu
Chris
Anzeige
AW: Laufzeit - automatischer Aufruf von Subs
21.02.2023 10:19:22
Subs
Hey,
danke schonmal für die Antwort. Die EnableEvents Befehle hatten wir noch nicht drin, ich glaube die haben jetzt schonmal wenigstens ein bisschen was gebracht.
Generell handelt es sich um etwa 10000 Zeilen. Beim sortieren sollen zunächst mehrere ID-Spalten nach Größe sortiert werden und dann miteinander verglichen werden, sodass gleiche IDs in der gleichen Zeile stehen und manche Zeilen dann eventuell teilweise leer sind. Ich würde also vermuten, dass es eine recht umfangreiche Berechnung ist. Ich kann den code aber auch gerne einmal teilen (ist vermutlich aber doch sehr spezifisch), vielleicht hast du ja noch Ideen:

Public Sub sortieren()
    Application.EnableEvents = False
    Application.Calculation = xlManual
    Application.ScreenUpdating = False
    Worksheets("Hilfsblatt").Activate
    
    For i = 6 To 200
        If InStr(Worksheets("Hilfsblatt").Cells(1, i).Value, "Mitarbeiter") > 0 Then
            Worksheets("Hilfsblatt").Cells(1, i).Value = "Mitarbeiter"
        End If
    Next i
    Dim anzEinträge As Integer
    anzEinträge = 0
    Do
        anzEinträge = anzEinträge + 1
    Loop Until Worksheets("Hilfsblatt").Cells(1, anzEinträge + 5) = "Mitarbeiter"
    Dim anzBlätter As Integer
    anzBlätter = 0
    For i = 6 To 200
        If InStr(Worksheets("Hilfsblatt").Cells(1, i).Value, "Mitarbeiter") > 0 Then
            Worksheets("Hilfsblatt").Cells(1, i).Value = "Mitarbeiter"
        End If
        If Worksheets("Hilfsblatt").Cells(1, i) = "Mitarbeiter" Then
            anzBlätter = anzBlätter + 1
        End If
    Next i
    Dim Bereich As String
    Bereich = ":"
    Dim sortNach As String
    Dim a As Integer
    zahl = 70
    Dim letzterEintrag As Integer
    Dim BereichzumKoppieren As String
    letzterEintrag = 0
    For i = 0 To anzBlätter - 1
        Bereich = Chr(zahl + i * anzEinträge) + ":" + Chr(zahl + i * anzEinträge + anzEinträge - 1)
        sortNach = Chr(zahl + i * anzEinträge + anzEinträge - 1) + "2"
        Range(Bereich).Sort key1:=Range(sortNach)
        If letzterEintrag  Worksheets("Hilfsblatt").Cells(Rows.Count, 6 + i * anzEinträge + anzEinträge - 1).End(xlUp).Row Then
            letzterEintrag = Worksheets("Hilfsblatt").Cells(Rows.Count, 6 + i * anzEinträge + anzEinträge - 1).End(xlUp).Row
        End If
    Next i
    For i = 2 To letzterEintrag + 500
        If Worksheets("Hilfsblatt").Cells(i, 6 + 0 * anzEinträge + anzEinträge - 1) > Worksheets("Hilfsblatt").Cells(i, 6 + 1 * anzEinträge + anzEinträge - 1) Then
            letzterEintragSpalte = Worksheets("Hilfsblatt").Cells(Rows.Count, 6 + 0 * anzEinträge + anzEinträge - 1).End(xlUp).Row
            BereichzumKoppieren = Chr(zahl + 0 * anzEinträge + anzEinträge - anzEinträge) + CStr(i) + ":" + Chr(zahl + 0 * anzEinträge + anzEinträge - 1) + CStr(letzterEintrag + 500)
            Worksheets("Hilfsblatt").Range(BereichzumKoppieren).Copy Destination:=Worksheets("Hilfsblatt").Range(Chr(zahl + 0 * anzEinträge + anzEinträge - anzEinträge) + CStr(i + 1))
            For j = 1 To anzEinträge
                Worksheets("Hilfsblatt").Cells(i, 6 + 0 * anzEinträge + anzEinträge - j) = ""
            Next j
        ElseIf Worksheets("Hilfsblatt").Cells(i, 6 + 0 * anzEinträge + anzEinträge - 1)  Worksheets("Hilfsblatt").Cells(i, 6 + 1 * anzEinträge + anzEinträge - 1) Then
            letzterEintragSpalte = Worksheets("Hilfsblatt").Cells(Rows.Count, 6 + 1 * anzEinträge + anzEinträge - 1).End(xlUp).Row
            BereichzumKoppieren = Chr(zahl + 1 * anzEinträge + anzEinträge - anzEinträge) + CStr(i) + ":" + Chr(zahl + 1 * anzEinträge + anzEinträge - 1) + CStr(letzterEintrag + 500)
            Worksheets("Hilfsblatt").Range(BereichzumKoppieren).Copy Destination:=Worksheets("Hilfsblatt").Range(Chr(zahl + 1 * anzEinträge + anzEinträge - anzEinträge) + CStr(i + 1))
            For j = 1 To anzEinträge
                Worksheets("Hilfsblatt").Cells(i, 6 + 1 * anzEinträge + anzEinträge - j) = ""
            Next j
        End If
    Next i
    letzteZeile1 = Worksheets("Hilfsblatt").Cells(Rows.Count, 6).End(xlUp).Row
    letzteSpalte1 = Worksheets("Hilfsblatt").Cells(1, Columns.Count).End(xlToLeft).Column
    Worksheets("Benutzeroberfläche").Range("B2:" + Chr(64 + letzteSpalte1 - 4) + CStr(letzteZeile1)).Value = Worksheets("Hilfsblatt").Range("F1:" + Chr(64 + letzteSpalte1) + CStr(letzteZeile1 - 1)).Value
    Worksheets("Benutzeroberfläche").Range("B1:" + Chr(64 + letzteSpalte1 - 4) + "1").Value = Worksheets("Hilfsblatt").Range("F" + CStr(letzteZeile1) + ":" + Chr(64 + letzteSpalte1) + CStr(letzteZeile1)).Value
    Dim Mitarbeiterausgewählt As Boolean
    Mitarbeiterausgewählt = True
    For i = 1 To 7
        If Not Worksheets("Hilfsblatt").Cells(i, 4) Like "Mitarbeiter ausgewählt" Then
            Mitarbeiterausgewählt = False
        End If
    Next i
    If Mitarbeiterausgewählt = False Then
        For i = 2 To 100
            If Worksheets("Benutzeroberfläche").Cells(1, i) Like "Mitarbeiter" Then
                Worksheets("Benutzeroberfläche").Columns(i).Delete
                i = i - 1
            End If
        Next i
    End If
    letzteSpalte = Worksheets("Benutzeroberfläche").Cells(1, Columns.Count).End(xlToLeft).Column
    For i = 2 To letzteSpalte
        Worksheets("Benutzeroberfläche").Cells(1, i).Interior.ColorIndex = 35
    Next i
    Worksheets("Benutzeroberfläche").Columns("A:ZZ").AutoFit
    
    Worksheets("Benutzeroberfläche").Activate
    Application.Calculation = xlAutomatic
    Application.ScreenUpdating = True
    Application.EnableEvents = True
End Sub
Danke schonmal.
LG Finn64
Anzeige
AW: Laufzeit - automatischer Aufruf von Subs
21.02.2023 17:25:27
Subs
Hi
Die Zeile betr. Events bringt nur etwas, wenn du auch tatsächlich Events (Ereignis-Prozeduren) verwendest. Evtl. war der erzielte Effekt eher psychologischer Natur. Wenn keine Ereignisse verwendet werden, würde ich die Zeile eher wieder entfernen (ansonsten empfiehlt es sich zusätzlich ein Error-Handling zu ergänzen).
Mit dem Vorschlag Calculation/Events wollte ich möglich Ursachen für die generell lange Laufzeit ausschliessen. Inzwischen wird jedoch deutlich, dass es eher am VBA-Code selber liegt u.a. die Schleifen. Hierzu hast du ja bereits diverse Inputs von verschiedenen Profis bekommen, die es erst einmal zu verarbeiten gilt.
cu
Chris
Anzeige
AW: Laufzeit - automatischer Aufruf von Subs
21.02.2023 11:36:35
Subs
Hallo,
die ersten 3 Schleifen kannst du zu einer reduzieren.
Was soll das?: Bereich = Chr(zahl + i * anzEinträge) + ":" + Chr(zahl + i * anzEinträge + anzEinträge - 1)
Das knallt, wenn zahl + i * anzEinträge &gt 90 wird.
Außerdem werden Texte mit & statt + verknüpft.
Gruß
Rudi
AW: Laufzeit - automatischer Aufruf von Subs
21.02.2023 12:15:21
Subs
Hey Rudi,
Dass Chr(...) mit Werten größer 90 nicht mehr funktioniert, da hatte ich gar nicht drüber nachgedacht. Hast du da eine Idee, wie man das umgehen könnte?
LG Finn64
AW: Laufzeit - automatischer Aufruf von Subs
21.02.2023 12:41:13
Subs
Hast du da eine Idee,
sogar mehrere.
Erst mal solltest du weg von den Strings und direkt Ranges referenzieren.
z. B.
Dim Bereich as Range, sortNach as Range
    For i = 0 To anzBlätter - 1
        Set Bereich = Range(Columns(6 + i * anzEinträge), Columns(6 + i * anzEinträge + anzEinträge - 1)
        Set sortNach = cells(2, 6 + i * anzEinträge + anzEinträge - 1) 
        Bereich.Sort key1:=sortNach
Über die Sinnhaftigkeit deiner Berechnungen bzw. des ganzen Codes lasse ich mich jetzt nicht aus.
Gruß
Rudi
Anzeige
AW: Laufzeit - automatischer Aufruf von Subs
21.02.2023 12:02:57
Subs
Hi
das einfachste wäre, wenn du für den Button ein drittes Makro schreibst, das dann diese beiden Makros nacheinander aufruft.
warum die Rechenzeit so hoch geht, lässt sich so allgemein ohne die Datei zu haben um zu schauen, was da genau passiert, nicht sagen.
Wenn man mit den GetMoreSpeed-Einstellungen arbeitet (Bildschirmaktualisierung aus, Automatische Neuberechnung der Formeln aus, Events aus), dann muss man aufpassen, wann und wo man diese ein- und ausschaltet, damit sie nicht plötzlich dort nicht aktiv sind, wo man es eigentlich erwartet.
diese Aufgabe:
Beim sortieren sollen zunächst mehrere ID-Spalten nach Größe sortiert werden und dann miteinander verglichen werden, sodass gleiche IDs in der gleichen Zeile stehen und manche Zeilen dann eventuell teilweise leer sind.
lässt sich am einfachsten und wahrscheinlich schnellsten so lösen:
Schritt 1:
wenn du die Tabellen A und B hast, dann kopiere die die IDs von B und füge sie unter die IDs von A ein, ebenso kopierst du die IDs von A und fügst sie unter die IDs von B ein, so dass am Schluss in diesen Spalten alle vorkommenden IDs vorhanden sind
Schritt 2:
Wende dann in diesen Spalten das DATEN - DATENTOOLS - DUPLIKATE ENTFERNEN an (VBA: RemoveDuplicates). dann verschwinden in den unten angefügten IDs diejenigen, die schon in der Tabelle vorhanden sind.
jetzt sollte in jeder Tabelle jede ID-Nummer aus allen Tabellen einmal vorhanden sein
Schritt 3:
sortiere jetzt die Tabellen nach dieser Spalte.
Dann hast du in jeder Tabelle die IDs in der selben Zeile, mit den Leerzeilen dazwischen.
Gruß Daniel
Anzeige
AW: Laufzeit - automatischer Aufruf von Subs
21.02.2023 12:05:53
Subs
+ anzEinträge - anzEinträge ?
+ 0 * anzEinträge + anzEinträge - 1 ?
1 * anzEinträge + anzEinträge - anzEinträge ?
Was soll der Quatsch? Welches Mathegenie hat das erstellt ? Oder wurde der "Programmierer" pro Buchstaben bezahlt ?
AW: Laufzeit - automatischer Aufruf von Subs
21.02.2023 12:15:47
Subs
= Chr(zahl + 0 * anzEinträge + anzEinträge - anzEinträge)
finde ich noch am Besten - werde ich für den Nobelpreis für Mathematik vorschlagen.
AW: Laufzeit - automatischer Aufruf von Subs
21.02.2023 12:34:45
Subs
Du kennst offenbar nur die A1-Schreibweise und nicht die Z1S1-Schreibweise.
Statt das
Worksheets("Benutzeroberfläche").Range("B2:" + Chr(64 + letzteSpalte1 - 4) + CStr(letzteZeile1)).Value = Worksheets("Hilfsblatt").Range("F1:" + Chr(64 + letzteSpalte1) + CStr(letzteZeile1 - 1)).Value
das
Set wks1=Worksheets("Benutzeroberfläche")
Set wks2=Worksheets("Hilfsblatt")
wks1.Range(wks1.Cells(2,2),wks1.Cells(letzteZeile1,letzteSpalte1 - 4).Value=wks2.Range(wks2.Cells(1,6), wks2Cells(letzteZeile1 - 1, letzteSpalte1) 

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige