Чи є код у VBA, я можу обернути функцію, яка дасть мені знати час, необхідний для запуску, щоб я міг порівняти різні періоди роботи функцій?
Чи є код у VBA, я можу обернути функцію, яка дасть мені знати час, необхідний для запуску, щоб я міг порівняти різні періоди роботи функцій?
Відповіді:
Якщо ваші функції не дуже повільні, вам знадобиться таймер із високою роздільною здатністю. Найточніший, який я знаю, - це QueryPerformanceCounter
. Погугліть для отримання додаткової інформації. Спробуйте вставити наступне в клас, зателефонуйте йому CTimer
сказати, тоді ви можете зробити екземпляр десь глобально і просто зателефонувати .StartCounter
і.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()
дає результат у мілісекундах. Я не застосував жодної компенсації накладних витрат, оскільки мене більше турбував ефект заїкання при розрахунку накладних витрат, ніж ідеальна точність.
GetTickCount
з kernel32).
StartCounter
І TimeElapsed
? Я зробив екземпляр Timer CTimer
на початку, і With StartCounter
я просто написав .StartCounter
після того, як моя підручна програма почала, .TimeElapsed
і це мені відповіло Invalid use of property
. Коли я не .StartCounter
кажучи вже, це говорить мені, що об'єкт не встановлений.
Declare PtrSafe Function
stackoverflow.com/questions/21611744 / ...
Функція таймера у VBA дає вам кількість секунд, що минули з півночі, до 1/100 секунди.
Dim t as single
t = Timer
'code
MsgBox Timer - t
Якщо ви намагаєтесь повернути час, як секундомір, ви можете використовувати наступний API, який повертає час у мілісекундах з моменту запуску системи:
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
після http://www.pcreview.co.uk/forums/grab-time-milliseconds-included-vba-t994765.html (оскільки timeGetTime у winmm.dll у мене не працював, а QueryPerformanceCounter був занадто складним для необхідного завдання)
Public Declare Function ...
частина? Це створює помилку під час додавання вашого коду внизу мого
Для новачків за цими посиланнями пояснюється, як зробити автоматичне профілювання всіх підводних пристроїв, за якими ви хочете стежити за часом:
http://www.nullskull.com/a/1602/profiling-and-optimizing-vba.aspx
http://sites.mcpher.com/share/Home/excelquirks/optimizationlink див. procProfiler.zip у 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
Вихід:
Час роботи: 00:00:02
Ми використовували рішення на основі timeGetTime у winmm.dll для точності мілісекунд протягом багатьох років. Див. Http://www.aboutvb.de/kom/artikel/komstopwatch.htm
Стаття німецькою мовою, але код завантаження (клас VBA, що обертає виклик функції dll) досить простий у використанні та розумінні, не маючи можливості прочитати статтю.
Секунди з 2 десятковими пробілами:
Dim startTime As Single 'start timer
MsgBox ("run time: " & Format((Timer - startTime) / 1000000, "#,##0.00") & " seconds") 'end timer
Мілісекунди:
Dim startTime As Single 'start timer
MsgBox ("run time: " & Format((Timer - startTime), "#,##0.00") & " milliseconds") 'end timer
Мілісекунди з розділювачем комами:
Dim startTime As Single 'start timer
MsgBox ("run time: " & Format((Timer - startTime) * 1000, "#,##0.00") & " milliseconds") 'end timer
Просто залишаю це тут для тих, хто шукав простий таймер, відформатований із секундами до 2 знаків після коми, як я. Це короткі та солодкі маленькі таймери, якими я люблю користуватися. Вони займають лише один рядок коду на початку підпрограми або функції і один рядок коду знову в кінці. Вони не призначені для божевільних точних, мені, як правило, байдуже ні про що менше 1/100 секунди особисто, але таймер мілісекунд дасть вам найбільш точний час роботи з цих 3. Я також вас прочитав може отримати неправильне зчитування, якщо трапляється, що він працює під час перетину опівночі, рідкісний приклад, але просто FYI.