Thanks Dwight and Sean.
My example is quite simple, but with some data-type testing/object testing and decent error-handling, I think you could expand this "idea" into more advanced Subs/Functions.
Instead of setting the method to accept a fixed amount of parameters, set it to accept one object. In my example, I use a Class that allows you to add different objects (through a variant-array).
There is (at least) one weakness with this approach. You can't add arrays to the Argument-object, as (from what I've read) an array can't contain another array. If it's a string array, you could implode the array, add a symbol at the front of the string to identify it as an array, and split it in the receiving function.
Screenshots of test-agent:
Dim s As New NotesSession
Dim args As New Arguments
Dim doc As NotesDocument
Set doc = s.CurrentDatabase.CreateDocument
doc.subject = "Some mostly harmless planet"
Call args.add( "Tommy Valand" )
Call argumentsAsObject( args )
Call args.add( doc )
Call argumentsAsObject( args )
Call args.add( "Always pack your towel!" )
Call argumentsAsObject( args )
The Arguments-class
The argumentsAsObject-sub
The test-agent
Code in a text-file
The Arguments class:
'argsdemo scriptlib
Class Arguments
Private counter As Integer
Private args() As Variant
Public Sub add( var As Variant)
Redim Preserve args( counter )
If Isobject ( var ) Then
Set args( counter ) = var
Else
args( counter ) = var
End If
counter = counter + 1
End Sub
Public Function getNth( nth As Integer ) As Variant
If Isobject ( args(nth) ) Then
Set getNth = args(nth)
Else
getNth = args(nth)
End If
End Function
Public Function getAll As Variant
getAll = args
End Function
Public Function length As Integer
length = Ubound( args ) + 1
End Function
End Class
Sub that take one parameter (As Arguments):
'accept an Arguments-object
Sub argumentsAsObject( args As Arguments )
Select Case args.length
Case 1
Msgbox "Name: " + args.getNth(0)
Case 2
Msgbox "Name: " + args.getNth(0) + Chr(13) +_
"Address: " + args.getNth(1).subject(0)
Case Else
Dim strTemp As String
Dim counter As Integer
Forall item In args.getAll
'35 - Product object (I know it's a NotesDocument)
If Datatype( item ) = 35 Then
strTemp = strTemp + "Item at index " +_
Cstr( counter ) + ": doc[" + item.subject(0) + "]" + Chr(13)
Else
strTemp = strTemp + "Item at index " +_
Cstr( counter ) + ": " + item + Chr(13)
End If
counter = counter + 1
End Forall
Msgbox strTemp
End Select
End Sub
Full code for the test-agent:
'options
Option Public
Option Declare
Use "argsdemo"
Sub Initialize
Dim s As New NotesSession
Dim args As New Arguments
Dim doc As NotesDocument
Set doc = s.CurrentDatabase.CreateDocument
doc.subject = "Some mostly harmless planet"
Call args.add( "Tommy Valand" )
Call argumentsAsObject( args )
Call args.add( doc )
Call argumentsAsObject( args )
Call args.add( "Always pack your towel!" )
Call argumentsAsObject( args )
End Sub
If you have an easier way to allow this kind of flexibility please let me know.
3 comments:
I was thinking about solving this issue with passing a list of variants as a parameter. But, I have not come up to the need yet.
Sub SubC()
Dim args List As Variant
Set args("session") = New notessession
args("num") = 1
args("str") = "string"
Call funcC( args)
End Sub
Sub FuncC( args List As Variant)
Print "session.EffectiveUserName=" & args("session").EffectiveUserName
Print "num=" & Cstr( args( "num"))
Print "str=" & args( "str")
End Sub
I had the exact same thought as Dwight when I was reading your post. Lists are great for handling collections of disparate things. Plus, you can make a List contain another List. Very OO way of looking at and handling data. And because Lists are accessed via parameter name and not a subscript number, you could make the list really dynamic.
You know what, I hadn't thought of that approach.. :)
Another fun thing with lists is the ListTag:
Sub stampDocuments( args List As Variant )
Dim s As New NotesSession
Dim tempDoc As NotesDocument
Forall arg In Args
%REM
document[ int ] ->
NotesDocument
documentId[ int ] ->
NotesDocument.UniversalID
%ENDREM
If Instr( ListTag( arg ), "Id" Then
Set tempDoc = s.CurrentDatabase.GetDocumentByUNID( arg )
Else
Set tempDoc = arg
End If
tempDoc.stamped = "stamped"
End Forall
End Sub
Post a Comment