VERSION 1.0 CLASS
BEGIN
MultiUse = -1
END
Attribute VB_Name = "stdPerformance"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Private Declare Function GetTickCount Lib "/Applications/Microsoft Excel.app/Contents/Frameworks/MicrosoftOffice.framework/MicrosoftOffice" () As Long
#Else
Private Declare Function GetTickCount Lib "Applications:Microsoft Office 2011:Office:MicrosoftOffice.framework:MicrosoftOffice" () As Long
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
Private Declare Function GetTickCount Lib "kernel32" () As Long
Public Enum EPerfObjType
iMeasure=1
iOptimiser=2
End Enum
Private pObjType as EPerfObjType
Private pEnableEvents as boolean
Private pScreenUpdating as boolean
Private pCalculation as long
Private pStartTime as long
Private pKeyName as string
Private pDivider as double
Private Type FakeDictItem
key as string
val as variant
End Type
Private FakeDict() as FakeDictItem
Public Function Create(ByVal objType as EPerfObjType, ByVal params as Variant) as stdPerformance
Set Create = new stdPerformance
Call Create.init(objType, params)
End Function
Public Sub Init(ByVal objType as EPerfObjType, ByVal params as variant)
pObjType = objType
select case objType
case iMeasure
pKeyName = params(0)
pDivider = params(1)
pStartTime = GetTickCount()
case iOptimiser
pScreenUpdating = Application.ScreenUpdating
pEnableEvents = Application.EnableEvents
Application.ScreenUpdating = params(0)
Application.EnableEvents = params(1)
select case Application.Name
case "Microsoft Excel"
pCalculation = Application.Calculation
Application.Calculation = params(2)
end select
end select
End Sub
Public Function Measure(ByVal sProc as string, Optional ByVal nCount as double=1) as stdPerformance
set Measure = stdPerformance.Create(iMeasure, Array(sProc,nCount))
End Function
Public Function Optimise(Optional ByVal ScreenUpdating as boolean = false, Optional ByVal EnableEvents as boolean = false, Optional ByVal Calculation as long = -4135) as stdPerformance
set Optimise = stdPerformance.Create(iOptimiser, Array(ScreenUpdating,EnableEvents,Calculation))
End Function
Public Property Get Measurement(ByVal sKey As String) As Double
If Me Is stdPerformance Then
Dim v: v = getDictItem(sKey)
If TypeName(v) = "Variant()" Then
Measurement = getDictItem(sKey)(0)
Else
Measurement = Empty
End If
End If
End Function
Public Sub AddMeasurement(ByVal sKey as string, ByVal time as Double, ByVal nCount as Double)
if Me is stdPerformance then
Debug.Print sKey & ": " & time & " ms" & iif(nCount>1," (" & (1000*time/nCount) & chr(181) & "s per operation)","")
Dim ind as long: ind = getDictIndex(sKey)
if ind = -1 then
Call setDictItem(sKey, Array(time,1))
else
Dim vItem: vItem = getDictItem(sKey)
Dim average as long: average = vItem(0)
Dim count as long: count = vItem(1) + 1
average = average + (time - average)/count
Call setDictItem(sKey, Array(average,count))
end if
end if
End Sub
Public Sub MeasuresClear()
ReDim FakeDict(0 to 0)
End Sub
Public Property Get MeasuresKeys() as string()
if Me is stdPerformance then
if ubound(FakeDict) = 0 then
MeasuresKeys = Split("")
else
Dim sOut() as string
Redim Preserve sOut(0 to ubound(FakeDict)-1)
Dim i as long
For i = 0 to ubound(FakeDict)-1
sOut(i) = FakeDict(i).key
next
MeasuresKeys = sOut
end if
end if
End Property
Private Sub Class_Initialize()
if me is stdPerformance then
Redim FakeDict(0 to 0)
end if
End Sub
Private Sub Class_Terminate()
if not me is stdPerformance then
select case pObjType
case iMeasure
Dim pEndTime as long: pEndTime = GetTickCount()
Call stdPerformance.AddMeasurement(pKeyName, Abs(pEndTime - pStartTime),pDivider)
case iOptimiser
Application.ScreenUpdating = pScreenUpdating
Application.EnableEvents = pEnableEvents
select case Application.Name
case "Microsoft Excel"
Application.Calculation = pCalculation
end select
end select
end if
End Sub
Private Function getDictIndex(ByVal key as string) as Long
On Error GoTo ErrorOccurred
Dim i as long
For i = 0 to ubound(FakeDict)
if FakeDict(i).key = key then
getDictIndex = i
Exit Function
end if
next
On Error Goto 0
ErrorOccurred:
getDictIndex = -1
End Function
Private Sub setDictItem(ByVal key as string, ByVal v as variant, Optional ByVal ind as long = -1)
if ind = -1 then ind = getDictIndex(key)
if ind = -1 then
ind = getUB(FakeDict)
FakeDict(ind).key = key
Redim Preserve FakeDict(0 to ind+1)
end if
if isObject(v) then
set FakeDict(ind).val = v
else
FakeDict(ind).val = v
end if
End Sub
Private Function getUB(ByRef items() As FakeDictItem) As Long
On Error GoTo ErrorOccurred
getUB = UBound(items)
Exit Function
ErrorOccurred:
getUB = -1
End Function
Private Function getDictItem(ByVal key as string) as variant
Dim ind as Long: ind = getDictIndex(key)
if ind <> -1 then
if isObject(FakeDict(ind).val) then
set getDictItem = FakeDict(ind).val
else
getDictItem = FakeDict(ind).val
end if
else
getDictItem = Empty
end if
End Function