Gibt es Code in VBA, mit dem ich eine Funktion umbrechen kann, der mir die Ausführungszeit mitteilt, damit ich die verschiedenen Laufzeiten von Funktionen vergleichen kann?
Gibt es Code in VBA, mit dem ich eine Funktion umbrechen kann, der mir die Ausführungszeit mitteilt, damit ich die verschiedenen Laufzeiten von Funktionen vergleichen kann?
Antworten:
Wenn Ihre Funktionen nicht sehr langsam sind, benötigen Sie einen Timer mit sehr hoher Auflösung. Das genaueste, das ich kenne, ist QueryPerformanceCounter
. Google es für weitere Informationen. Versuchen Sie, Folgendes in eine Klasse zu verschieben, nennen Sie es CTimer
say, dann können Sie eine Instanz irgendwo global erstellen und einfach .StartCounter
und aufrufen.TimeElapsed
Option Explicit
Private Type LARGE_INTEGER
lowpart As Long
highpart As Long
End Type
Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As LARGE_INTEGER) As Long
Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As LARGE_INTEGER) As Long
Private m_CounterStart As LARGE_INTEGER
Private m_CounterEnd As LARGE_INTEGER
Private m_crFrequency As Double
Private Const TWO_32 = 4294967296# ' = 256# * 256# * 256# * 256#
Private Function LI2Double(LI As LARGE_INTEGER) As Double
Dim Low As Double
Low = LI.lowpart
If Low < 0 Then
Low = Low + TWO_32
End If
LI2Double = LI.highpart * TWO_32 + Low
End Function
Private Sub Class_Initialize()
Dim PerfFrequency As LARGE_INTEGER
QueryPerformanceFrequency PerfFrequency
m_crFrequency = LI2Double(PerfFrequency)
End Sub
Public Sub StartCounter()
QueryPerformanceCounter m_CounterStart
End Sub
Property Get TimeElapsed() As Double
Dim crStart As Double
Dim crStop As Double
QueryPerformanceCounter m_CounterEnd
crStart = LI2Double(m_CounterStart)
crStop = LI2Double(m_CounterEnd)
TimeElapsed = 1000# * (crStop - crStart) / m_crFrequency
End Property
TimeElapsed()
gibt das Ergebnis in Millisekunden an. Ich habe keine Overhead-Kompensation implementiert, da ich mir mehr Sorgen über die Auswirkung eines Ruckelns bei der Overhead-Berechnung als über die perfekte Genauigkeit gemacht habe.
GetTickCount
aus Kernel32).
StartCounter
Und TimeElapsed
? Ich habe CTimer
am Anfang einen Instanz-Timer von gemacht und With StartCounter
ich habe gerade geschrieben, .StartCounter
nachdem mein Sub angefangen hat und .TimeElapsed
und es hat mir geantwortet Invalid use of property
. Wenn ich geschweige .StartCounter
denn sage, dass ein Objekt nicht gesetzt ist.
Declare PtrSafe Function
stackoverflow.com/questions/21611744/…
Die Timer-Funktion in VBA gibt Ihnen die Anzahl der seit Mitternacht verstrichenen Sekunden auf 1/100 Sekunde an.
Dim t as single
t = Timer
'code
MsgBox Timer - t
Wenn Sie versuchen, die Zeit wie eine Stoppuhr zurückzugeben, können Sie die folgende API verwenden, die die Zeit seit dem Systemstart in Millisekunden zurückgibt:
Public Declare Function GetTickCount Lib "kernel32.dll" () As Long
Sub testTimer()
Dim t As Long
t = GetTickCount
For i = 1 To 1000000
a = a + 1
Next
MsgBox GetTickCount - t, , "Milliseconds"
End Sub
nach http://www.pcreview.co.uk/forums/grab-time-milliseconds-included-vba-t994765.html (da timeGetTime in winmm.dll für mich nicht funktionierte und QueryPerformanceCounter für die erforderliche Aufgabe zu kompliziert war)
Public Declare Function ...
Teil? Es erzeugt einen Fehler beim Hinzufügen Ihres Codes am Ende von mir
Für Neulinge wird unter diesen Links erläutert, wie Sie eine automatische Profilerstellung aller Subs durchführen, die Sie zeitlich überwachen möchten:
http://www.nullskull.com/a/1602/profiling-and-optimizing-vba.aspx
http://sites.mcpher.com/share/Home/excelquirks/optimizationlink siehe procProfiler.zip unter http://sites.mcpher.com/share/Home/excelquirks/downlable-items
Sub Macro1()
Dim StartTime As Double
StartTime = Timer
''''''''''''''''''''
'Your Code'
''''''''''''''''''''
MsgBox "RunTime : " & Format((Timer - StartTime) / 86400, "hh:mm:ss")
End Sub
Ausgabe:
Laufzeit: 00:00:02
Wir haben seit vielen Jahren eine auf timeGetTime basierende Lösung in winmm.dll für Millisekundengenauigkeit verwendet. Siehe http://www.aboutvb.de/kom/artikel/komstopwatch.htm
Der Artikel ist in deutscher Sprache, aber der Code im Download (eine VBA-Klasse, die den DLL-Funktionsaufruf umschließt) ist einfach genug zu verwenden und zu verstehen, ohne den Artikel lesen zu können.
Sekunden mit 2 Dezimalstellen:
Dim startTime As Single 'start timer
MsgBox ("run time: " & Format((Timer - startTime) / 1000000, "#,##0.00") & " seconds") 'end timer
Millisekunden:
Dim startTime As Single 'start timer
MsgBox ("run time: " & Format((Timer - startTime), "#,##0.00") & " milliseconds") 'end timer
Millisekunden mit Komma-Trennzeichen:
Dim startTime As Single 'start timer
MsgBox ("run time: " & Format((Timer - startTime) * 1000, "#,##0.00") & " milliseconds") 'end timer
Lassen Sie dies hier für alle, die nach einem einfachen Timer suchen, der wie ich mit Sekunden bis 2 Dezimalstellen formatiert ist. Dies sind kurze und süße kleine Timer, die ich gerne benutze. Sie nehmen nur eine Codezeile am Anfang des Unter- oder Funktionsbereichs und am Ende wieder eine Codezeile ein. Diese sollen nicht verrückt genau sein, ich persönlich kümmere mich im Allgemeinen nicht um weniger als eine Hundertstelsekunde, aber der Millisekunden-Timer gibt Ihnen die genaueste Laufzeit dieser 3. Ich habe Sie auch gelesen kann die falsche Anzeige erhalten, wenn es während der Überquerung von Mitternacht läuft, eine seltene Instanz, aber nur zu Ihrer Information.