DIR – not that simple


I was writing a simple agent in Lotuscript to parse all the text files in a directory in order to load .eml files into a form. Obviously the first thing was to get the eml files downloaded and then run through a loop to process them. I noticed when looking at the Domino server console – an error message – “Illegal function call” which appear to relate to the DIR function call. I checked the reference where I had picked up the code and it was exactly the code I used – then was intrigued to find this

Problem
A LotusScript agent that uses the Dir function results in the following error:

“Illegal function call”

This occurs in cases where the code uses the Dir function in a subroutine (or function). The error occurs when the function is called again after being called within the subroutine (or function).

For example:

The application below was designed to cycle through both files and subdirectories. The application calls the subroutine Sub1 when a subdirectory is encountered. Once the subroutine has been exited and the Dir function is called again, the error occurs.

Option Public
%INCLUDE “lsconst.lss”

Sub Initialize
filelevel1$ = Dir$(“C:”, ATTR_DIRECTORY)
While (filelevel1$ <> “”)
If Instr(1, filelevel1$,”.”)=0 Then Call sub1(filelevel1$)
‘ The line below triggers the error “Illegal Function Call”
filelevel1$ = Dir$()
Wend
End Sub

Sub sub1(level1 As Variant)
If Instr(1, level1,”.”)=0 Then filelevel2$ = Dir$(“C:”+level1+”*.*”)
While (filelevel2$ <> “”)
‘ Perform desired operation on file in sub-directory
‘ Below accesses next file in sub-directory
filelevel2$=Dir()
Wend
End Sub

Solution
A request to clarify the documentation on this issue has been submitted to Lotus Quality Engineering.
This is a limitation of the Dir function. This function is not designed to operate in a recursive manner; it does not save a history of the calls made to it.

Workaround:

NOTE: The following workaround is an example only. Lotus Notes Support will not provide additional modifications to the example. It is provided as a sample of one way to approach a workaround and is intended for experienced LotusScript programmers.

You can work around this issue to some degree. The example below will only enable access to one level of subdirectories below the initial given directory. It will not cycle through subdirectory levels below that (in other words, subdirectories two levels below the given directory).

The code contains an updated version of the Initialize subroutine from the example given in the Problem section above. The Sub1 subroutine and the ‘Option Public’ code would be used as in the example above. The subroutine below cycles through the root directory and constructs an array of the files and subdirectories it finds. This array is then looped through. Because the code loops through the array, you do not need to subsequently call the Dir function, and this avoids the error. An If condition is used to determine whether a subdirectory has been found, and in that case only is the subroutine Sub1 called.

Sub Initialize
Dim filelist() As String
count=0
Filelevel1$ = Dir$(“C:”, ATTR_DIRECTORY)
While (filelevel1$ <> “”)
Redim Preserve Filelist(count)
Filelist(count) = Filelevel1$
count = count + 1
Filelevel1$=Dir$()
Wend
For i = 0 To count-1
filelevel1$ = Filelist(i)
If Instr(1, filelevel1$,”.”)=0 Then
‘ We have a sub-dir:
Call sub1(filelevel1$)
Else
‘We have a file. Perform desired check or operation
End If
Next
End Sub