Question

I'm trying to implement logger for Excel, which WONT logg user changes to cell values (who cares...).

But internal dynamics of my app.

So:

  1. It must be sheet based. (Cause user wont be able to remember to attach some strange files from strange locations...)
  2. It must be easily excel-able. (Excel is quite good at simple analytics, right? I do not want to write any custom parser for logs. Just use built in functionality of Excel)
  3. It must be elastic, when sometimes I will log additonal info, sometimes those will be variables, sometimes arrays, objects, etc.

Q: How to handle 3)? ParamArray will treat incoming array as single element. While using Array/Collection require preprocessing of scalar values into one item arrays/collections when loggin.

Here is my code so far:

Public Sub Log(level As LoggerSeverityLevel, functionName As String, message As   String, Optional Arguments As Variant)
Dim sh As Object
Set sh = ActiveSheet

LoggerDB.Activate
''' Find blank row for next entry
Dim firstEmptyRow As LongLong
firstEmptyRow = Range("A" & rows.count).End(xlUp).row + 1

''' Parse level into human redable format
Dim lvlMessage As String
lvlMessage = "Unknown"
If level = lslInfo Then lvlMessage = "Info"
If level = lslWarning Then lvlMessage = "Warning"
If level = lslDebug Then lvlMessage = "Debug"
If level = lslCritical Then lvlMessage = "Critical"

''' Insert data
LoggerDB.Cells(firstEmptyRow, 1) = Now()
LoggerDB.Cells(firstEmptyRow, 2) = lvlMessage
LoggerDB.Cells(firstEmptyRow, 3) = functionName
LoggerDB.Cells(firstEmptyRow, 4) = message

''' And optional arguments, one cell per argument
Dim i As Long
Dim arg As Variant
i = 4
For Each arg In Arguments
    LoggerDB.Cells(firstEmptyRow, i) = CStr(arg)
    i = i + 1
Next arg

sh.Activate
End Sub
Was it helpful?

Solution

Public Sub Log(level As LoggerSeverityLevel, functionName As String, message As String,    Optional Arguments As Variant)
Dim sh As Object
Set sh = ActiveSheet

LoggerDB.Activate
''' Find blank row for next entry
Dim firstEmptyRow As LongLong
firstEmptyRow = Range("A" & rows.count).End(xlUp).row + 1

''' Parse level into human redable format
Dim lvlMessage As String
lvlMessage = "Unknown"
If level = lslInfo Then lvlMessage = "Info"
If level = lslWarning Then lvlMessage = "Warning"
If level = lslDebug Then lvlMessage = "Debug"
If level = lslCritical Then lvlMessage = "Critical"

''' Insert data
LoggerDB.Cells(firstEmptyRow, 1) = Now()
LoggerDB.Cells(firstEmptyRow, 2) = lvlMessage
LoggerDB.Cells(firstEmptyRow, 3) = functionName
LoggerDB.Cells(firstEmptyRow, 4) = message

''' And optional arguments, one cell per argument
Dim i As Long
Dim arg As Variant
i = 5
Dim tmp As Variant
Dim coll As Collection

This part pack scalars (number, string, bool, whatever single value) into collection. So I can always assume that if any additional arguments are passed, For Each will work.

It relay on TypeName() returning string with "()" for arrays.

If Not IsMissing(Arguments) Then ' If not iterable by for each (single variable) pack into collection. If Not (InStr(TypeName(Arguments), "()") <> 0 Or TypeName(Arguments) = "Collection" Or TypeName(Arguments) = "Dictionary") Then Set coll = New Collection coll.add Arguments Set tmp = coll Else tmp = Arguments End If

    For Each arg In tmp
        LoggerDB.Cells(firstEmptyRow, i) = CStr(arg)
        i = i + 1
    Next arg
End If

sh.Activate
End Sub
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top