Y a-t-il du code dans VBA avec lequel je peux encapsuler une fonction qui me fera savoir le temps qu'il a fallu pour s'exécuter, afin que je puisse comparer les différents temps d'exécution des fonctions?
Y a-t-il du code dans VBA avec lequel je peux encapsuler une fonction qui me fera savoir le temps qu'il a fallu pour s'exécuter, afin que je puisse comparer les différents temps d'exécution des fonctions?
Réponses:
À moins que vos fonctions ne soient très lentes, vous aurez besoin d'un minuteur à très haute résolution. Le plus précis que je connaisse est QueryPerformanceCounter
. Recherche le sur Google pour plus d'informations. Essayez de pousser ce qui suit dans une classe, appelez-le par CTimer
exemple, vous pouvez alors créer une instance quelque part dans le monde et simplement appeler .StartCounter
et.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()
donne le résultat en millisecondes. Je n'ai pas mis en place de compensation des frais généraux car j'étais plus inquiet de l'effet d'un bégaiement dans le calcul des frais généraux que d'une précision parfaite.
GetTickCount
depuis kernel32).
StartCounter
And TimeElapsed
? J'ai fait une instance de Timer CTimer
au début et With StartCounter
je viens d'écrire .StartCounter
après le début de mon sous-marin .TimeElapsed
et cela m'a répondu Invalid use of property
. Quand j'en ai encore .StartCounter
moins, cela me dit qu'un objet n'est pas défini.
Declare PtrSafe Function
stackoverflow.com/questions/21611744/…
La fonction Timer dans VBA vous donne le nombre de secondes écoulées depuis minuit, à 1/100 de seconde.
Dim t as single
t = Timer
'code
MsgBox Timer - t
Si vous essayez de renvoyer l'heure comme un chronomètre, vous pouvez utiliser l'API suivante qui renvoie l'heure en millisecondes depuis le démarrage du système:
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
après http://www.pcreview.co.uk/forums/grab-time-milliseconds-included-vba-t994765.html (car timeGetTime dans winmm.dll ne fonctionnait pas pour moi et QueryPerformanceCounter était trop compliqué pour la tâche nécessaire)
Public Declare Function ...
partie? Cela crée une erreur lors de l'ajout de votre code au bas du mien
Pour les nouveaux abeilles, ces liens expliquent comment effectuer un profilage automatique de tous les sous-marins que vous souhaitez surveiller dans le temps:
http://www.nullskull.com/a/1602/profiling-and-optimizing-vba.aspx
http://sites.mcpher.com/share/Home/excelquirks/optimizationlink voir procProfiler.zip dans 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
Production:
Durée: 00:00:02
Nous avons utilisé une solution basée sur timeGetTime dans winmm.dll pour une précision à la milliseconde pendant de nombreuses années. Voir http://www.aboutvb.de/kom/artikel/komstopwatch.htm
L'article est en allemand, mais le code dans le téléchargement (une classe VBA encapsulant l'appel de fonction dll) est assez simple à utiliser et à comprendre sans pouvoir lire l'article.
Secondes avec 2 espaces décimaux:
Dim startTime As Single 'start timer
MsgBox ("run time: " & Format((Timer - startTime) / 1000000, "#,##0.00") & " seconds") 'end timer
Millisecondes:
Dim startTime As Single 'start timer
MsgBox ("run time: " & Format((Timer - startTime), "#,##0.00") & " milliseconds") 'end timer
Millisecondes avec séparateur de virgule:
Dim startTime As Single 'start timer
MsgBox ("run time: " & Format((Timer - startTime) * 1000, "#,##0.00") & " milliseconds") 'end timer
Il suffit de laisser ceci ici pour tous ceux qui recherchaient une simple minuterie formatée avec des secondes à 2 espaces décimaux comme je l'étais. Ce sont des minuteries courtes et douces que j'aime utiliser. Ils n'occupent qu'une seule ligne de code au début de la sous ou de la fonction et une ligne de code à nouveau à la fin. Celles-ci ne sont pas censées être d'une précision folle, je ne me soucie généralement pas de moins de 1 / 100e de seconde personnellement, mais le minuteur en millisecondes vous donnera le temps d'exécution le plus précis de ces 3. Je vous ai aussi lu peut obtenir une lecture incorrecte si elle s'exécute pendant la traversée de minuit, une instance rare mais juste pour info.