Sunday, June 25, 2006

Logging events

Many of my applications involve processing huge (20,000+) numbers of document or template files.

Often some of these documents will baulk the process - especially documents with forms, ASK fields, or templates with stale references. For these applications I maintin an Exclusion file - a list of files I ought not to process; more on that in the next post.

For now I'll explain one method of dealing with awkward files.

I maintain a log file of events:
If os.strLogFile = strcTrue Then
Call Logger("ProcessProjectsOfFolder with " & strProjectList)
Else
End If


The slave function Logger obtains a valid name that will point into my Documents And settings folder:
Public Function Logger(strMsg As String)
Dim strLogFile As String
strLogFile = UW.STRFIXPATH(UW.strEnvironmentFactual(strcApplication))
strLogFile = strLogFile & "LogFile.txt"
Call logfile(strLogFile, strMsg)
End Function


The slave function LogFile prints to a file:
Public Function LogFile(strFile As String, strMsg As String)
' Procedure : LogFile
' Description: Time stamp a message string to a file.
' Copyright: Christopher Greaves
' Inputs: The local or full file name, a string.
' Returns: None.
' Assumes: None.
' Side Effects: None.
' Tested: By the calls shown below.
Call PrintFile(strFile, strDateTime & vbTab & strMsg)
'Sub TESTLogFile()
' Call LogFile("erase.txt", "Here is a first message") ' stored in macroContainer folder
' Call LogFile("c:\erase.txt", "Here is a second message") ' stored in boot root folder
' Call LogFile(MacroContainer.Path & Application.PathSeparator & "erase.txt", "Here is a third message")
'End Sub
End Function


While printFile merely opens, appends and closes a text file:
Public Function PrintFile(strFile As String, strMsg As String)
' Procedure : PrintFile
' Description: Print a message to a file.
' Copyright: Christopher Greaves
' Inputs: The local or full file name, a string.
' Returns: None.
' Assumes: None.
' Side Effects: None.
' Tested: By the calls shown below.
Dim intFile As Integer
intFile = FreeFile
Dim strWorkFile As String
strWorkFile = strFile
' add an extent if there is not one yet.
If InStr(1, strFile, strcExtentSeparatorDefaultValue) > 0 Then
Else
strWorkFile = strWorkFile & strcExtentTxt
End If
' add a path if there is not one yet.
If InStr(1, strFile, Application.PathSeparator) > 0 Then
Else
strWorkFile = strMacroContainerPathValue & strWorkFile
End If
Open strWorkFile For Append As #intFile
Print #intFile, strMsg
Close #intFile
End Function



That's an awful lot of code to say "I've started!", but note that PrintFile, and hence Logger, will have closed the file before the next statement is executed, so that no matter how the application crashes, I'll have a record of the file that triggered the failure, and can deal with it.

Tuesday, June 13, 2006

Parsing Strings

Available in my UW.DOT and UX.XLS libraries.
Nothing complex about it. We are often asked to split or parse strings into sub-strings.
Typically we receive a series of words separated by spaces or the comma character; sometimes separated by the tab character (vbTab in VBA)
We can peel off consecutive substrings in this manner:
Sub ParseStrings()
Dim strMyString As String
strMyString = "Nothing complex about it."
While Len(strMyString) > 0
MsgBox UW.strSplitAt(strMyString, " ")
Wend
End Sub
Of course, we need to know in advance what character to use as a delimiter.
Smart programming suggests that we adopt a convention of building a string of substrings by placing the delimiter as the first or left-most character:
strMyString = " Nothing complex about it."
Now we can write a parsing routine that is independent of the delimiter:
Sub ParseStrings()
Dim strMyString As String
strMyString = " Nothing complex about it."
Dim strDelimiter As String
strDelimiter = Left$(strMyString, 1)
While Len(strMyString) > 0
MsgBox UW.strSplitAt(strMyString, strDelimiter)
Wend
End Sub


Read more at http://www.chrisgreaves.com/BlogUtils/ParsingStrings.html)