2015-01-27 2 views
1

У нас возникают проблемы с производительностью с массивным листом. В частности, три операции кажутся очень медленными: вставить строку, удалить строку и отменить.Вычислить прошедшее время Excel для вставки строки

Я читал об оптимизации и хочу количественно определить, какие изменения действительно имеют значение. Для этого я хотел бы настроить VBA, который отслеживает прошедшее время для перечисленных выше событий, но я не могу найти никаких крючков.

Мне хотелось бы что-то вроде workheet_change_start, workheet_change_end, но я не нашел ничего подобного.

У меня была одна «отличная» идея, но она не сработала. Я думал, что сделаю две строки вставки назад, возьму отметку времени на каждом, а затем вычислим разницу ... но Excel перехитрил меня и собрал их как-то.

Заранее спасибо за ваши предложения

ПРИМЕЧАНИЕ: Благодаря ответы до сих пор. Я знаю о функции таймера, но я не могу понять, как захватить события, где я могу начать, и закончить таймер для некоторого поведения пользователя, например, до и после того, как пользователь вставляет строку.

ответ

2

Вы можете использовать небольшой макрос, например, как показано ниже, чтобы время, как долго он принимает ваше учебное пособие для выполнения действия

Dim t As Date 
t = Now() 
'your code for inserting new line here 
MsgBox Format(Now() - t, "hh:mm:ss") 

Источник: http://www.mrexcel.com/archive/VBA/20164.html

0

Вы можете использовать базовый класс таймера (от предыдущего SO question - reference tba), помещая его в класс (называемый CTimer). Преимущество такого подхода заключается в его повторном использовании.

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 

А затем в обычном модуле код вы можете использовать его как это:

Sub test_time() 
Dim time_this As New CTimer 
Dim ws As Worksheet 

Set ws = ThisWorkbook.Worksheets("Sheet1") 

time_this.StartCounter 

    ws.Rows("6:6").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove 
    ws.Rows("8:8").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove 

MsgBox time_this.TimeElapsed 

End Sub 
+0

Следует отметить, что эти импортируемые функции для 32-битной Excel/VBA. ** Для 64-разрядного Excel/VBA потребуется эквивалент PtrSafe ** (или обе версии с директивами компилятора). – Jeeped

Смежные вопросы