2008-10-13 30 views

Respuesta

67

A menos que sus funciones sean muy lentas, necesitará un temporizador de muy alta resolución. La más precisa que conozco es QueryPerformanceCounter. Google para obtener más información. Trate de empujar el siguiente en una clase, lo llaman CTimer decir, entonces puede presentar una instancia en algún lugar global y simplemente llamamos .StartCounter y .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 
+2

he implementado en Excel VBA (añadiendo en el techo como se menciona en este artículo de KB: http://support.microsoft.com/kb/172338. Funcionó muy bien. Gracias. –

+1

Gracias, esto también funciona bien para mí. 'TimeElapsed()' da el resultado en milisegundos. No implementé ninguna compensación general porque estaba más preocupado por el efecto de una tartamudez en el cálculo de gastos generales que por la precisión perfecta. – Justin

+1

Eso es algo escuchado (en líneas de código para administrar): si puede vivir con una precisión de ~ 10ms, la respuesta de @ Kodak a continuación le da el mismo resultado en una línea de código (importando 'GetTickCount' de kernel32). – BrainSlugs83

2

Hemos utilizado una solución basada en timeGetTime en winmm.dll para una precisión de milisegundos durante muchos años. Ver http://www.aboutvb.de/kom/artikel/komstopwatch.htm

El artículo está en alemán, pero el código en la descarga (una clase de VBA que envuelve la llamada a la función dll) es lo suficientemente simple de usar y comprender sin poder leer el artículo.

39

La función del temporizador en VBA le da el número de segundos transcurridos desde la medianoche, hasta 1/100 de segundo.

Dim t as single 
t = Timer 
'code 
MsgBox Timer - t 

Si necesita mayor resolución, simplemente ejecutaría la función 1,000 veces y dividiría el tiempo total en 1,000.

+15

Eso no funcionaría: no se puede obtener más resolución tomando el promedio así. –

+2

Aún así, si está midiendo el rendimiento en VBA, obtener una resolución de 1/100 de segundo no es malo. - Invocar las llamadas de tiempo solo podría tomar un par de ms. Si la llamada es tan rápida que necesita tanta resolución para cronometrarla, probablemente no necesite datos de rendimiento sobre esa llamada. – BrainSlugs83

+10

+1 para usar la función nativa. – RubberDuck

25

Si usted está tratando de volver el tiempo como un cronómetro se puede utilizar la siguiente API que devuelve el tiempo en milisegundos desde el inicio del sistema:

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 

después http://www.pcreview.co.uk/forums/grab-time-milliseconds-included-vba-t994765.html (como timeGetTime en winmm.dll no era trabajar para mí y QueryPerformanceCounter era demasiado complicado para que la tarea sea necesario)

+0

Esta es una gran respuesta. Nota: la * precisión * de los datos devueltos está expresada en milisegundos, sin embargo, el contador solo es * preciso * a aproximadamente 1/100 de segundo (es decir, podría estar apagado entre 10 y 16 ms) a través de MSDN: http : //msdn.microsoft.com/en-us/library/windows/desktop/ms724408 (v = vs.85) .aspx – BrainSlugs83

+0

hmm, si la resolución es la misma aquí que con el temporizador, entonces iría con el temporizador – Kodak

+0

¿Qué es la función 'Public Declare Function ...'? Crea un error al agregar tu código en la parte inferior de la mina – Marine1

Cuestiones relacionadas