Darren DICK
darrend at nimble.com.au
Sun Jan 29 22:51:19 CST 2006
Brilliant
Many thanks for that John
I am grateful
I never quite 'got into' classes
It was always on my to-do list
Now I virtually do nothing with Access <sigh>
I only lurk the list because of sentimental attachment :-)))
See ya
Darren
-----Original Message-----
From: accessd-bounces at databaseadvisors.com
[mailto:accessd-bounces at databaseadvisors.com] On Behalf Of John Colby
Sent: Monday, 30 January 2006 3:20 PM
To: 'Access Developers discussion and problem solving'
Subject: Re: [AccessD] Same form, different actions
>>The open Args are quite useful, but tacked on the end of a Do.cmd
statement they don't do much Just text or numbers (usually) tacked on the end of
an OpenForm Do.Cmd statement. The real 'power' is in the interpretation at the
other end
Darren,
First let me say that I have put up a demo on my site which shows how to use the
two classes in the following discussion. Go to my website -
www.colbyconsulting.com. If you haven't already, Register. Log in. Click
Example Code / Utilities. Select C2DbOpenArgs to download the demo.
I pass openargs in the form Varname1=VarVal1;VarName2=VarVal2;etc=etc1; This is
a syntax that has been around since early Access days and was used extensively
by, and perhaps even "invented by" Ken Getz. The = is used as the separator,
the semicolon as the delimiter.
I wrote a pair of classes which handle my openargs. A "control class" which I
name OpenArgs (plural) grabs the openargs string and parses the varname and
value for each openarg. It then instantiates a OpenArg (singular) class to
store this VarName and VarVal in. VarName is a string type, VarVal is a variant
type. Making it Variant causes an automatic coercion in a lot of cases -
currency values get turned into Currency variants, dates get turned into dates
etc. At any rate, each OpenArg instance is stored in a collection in the
OpenArgs (plural) class.
The OpenArgs class is dimensioned in the form header, and instantiated in the
OnOpen of the form. By the time it finishes loading, all of the OpenArgs are
parsed and sitting in OpenArg class instances in the collection in OpenArgs.
OpenArgs has a method for reading OpenArg instances from the collection.
OpenArg instances are stored in the collection keyed on the VarName.
Thus you have a pair of classes which automatically handles getting openargs for
you, one or a hundred, it doesn't matter, and it doesn't have to be
"re-invented" every time you want to get your openargs. Syntax is now
standardized everywhere in your app.
The form of course must know what openargs it is expecting, so it can now simply
call OpenArgs.Arg("VarName") and get back VarVal (a variant). What the form
does with the OpenArg is up to you, but getting the OpenArgs available to the
form is trivial.
All of the code follows. My clsOpenArgs (plural, the controller) also has the
ability to automatically interpret openargs as properties of the form.
In other words, if a param is passed in to clsOpenArgs that says to do so, then
if an OpenArg VarName is the same as a property of the form, the form property
is set to VarVal. I have actually demoed this in the state form, where the form
that opens frmState passes in the values for properties
strOpenArgs = "DataEntry=True;AllowEdits=True;AllowDeletions=False;"
The state form opens, the OpenArgs class parses the OpenArgs string passed in,
discovers that I want it to use the openargs to set form properties, and does
so.
Any OpenArgs which do not match the name of a form property are left
uninterpreted and the form can use them for whatever purpose you choose.
You can also not tell clsOpenArgs to interpret the openargs as form properties,
in which case all OpenArgs are left uninterpreted and you can do with them all
as you will.
The code:
'===========================================================
'Class OpenArg
'===========================================================
Option Compare Database
Option Explicit
'
'This class stores one OpenArg
'
Private mstrArgName As String
Private mvarArgVal As Variant
Private mblnIsProperty As Boolean
Function mInit(lstrArgName As String, lvarArgVal As Variant)
mstrArgName = lstrArgName
mvarArgVal = lvarArgVal
End Function
Function pName() As String
pName = mstrArgName
End Function
Function pVal() As Variant
pVal = mvarArgVal
End Function
Property Let pIsPrp(lmblnIsProperty As Boolean)
mblnIsProperty = lmblnIsProperty
End Property
Property Get pIsPrp() As Boolean
pIsPrp = mblnIsProperty
End Property
'===========================================================
'Class OpenArgs (Plural) - the controller class
'===========================================================
Option Compare Database
Option Explicit
'.
'.Written By : John W. Colby
'.Date Created : 04/10/2004
' Rev. History :
'
' BEHAVIORS:
'
'
'When a form opens, it can accept open args, a text string argument.
'The framework will check for openargs, and if they exist will check 'inside the
Openagrs for arguments named the same thing as form properties.
'If such arguments are found, the framework will set the form's property 'equal
to the argument value.
'
'I use this specifically to set up normal forms to be DataEntry forms '(only
allow new records to be added, not existing records edited) '
'I decided to encapsulate this functionality in a class to make the OpenArgs
'processing cleanly defined.
'
'--------------------------------------------------------------------------
'THESE CONSTANTS AND VARIABLES ARE USED INTERNALLY TO THE CLASS '*+ Class
constant declaration Private Const mcstrModuleName As String = "clsOpenArgs"
'*- Class constants declaration
'*+ Class variables declarations
'*- Class variables declarations
'.-------------------------------------------------------------------------
'THESE CONSTANTS AND VARIABLES ARE USED BY THE CLASS TO IMPLEMENT CLASS
FUNCTIONALITY '*+ custom constants declaration '
'*- Custom constants declaration
'*+ custom variables declarations
'
Private mfrm As Form 'A form reference passed in
Private mstrOpenArgs As String
Private mcolOpenArg As Collection
'*- custom variables declarations
'
'Define any events this class will raise here '*+ custom events Declarations
'Public Event MyEvent(Status As Integer)
'*- custom events declarations
'.-------------------------------------------------------------------------
'THESE FUNCTIONS / SUBS ARE USED INTERNALLY TO THE CLASS '*+ Private
Init/Terminate Interface Private Sub Class_Initialize() On Error GoTo
Err_Class_Initialize
Set mcolOpenArg = New Collection
Exit_Class_Initialize:
Exit Sub
Err_Class_Initialize:
MsgBox Err.Description, , "Error in Sub clsTemplate.Class_Initialize"
Resume Exit_Class_Initialize
Resume 0 '.FOR TROUBLESHOOTING
End Sub
Private Sub Class_Terminate()
On Error Resume Next
mTerm
End Sub
'INITIALIZE THE CLASS
Public Sub mInit(lfrm As Form, _
Optional blnApplyProperties As Boolean = False)
Set mfrm = lfrm
'The openargs string might be null
On Error Resume Next
mstrOpenArgs = mfrm.OpenArgs
ParseOpenArgs
'
'The default is false, do not try and apply OpenArgs as form properties
'If the deveopler wants to
'
If blnApplyProperties Then
ApplyFrmProperties
End If
End Sub
'CLEAN UP ALL OF THE CLASS POINTERS
Public Sub mTerm()
Static blnRan As Boolean 'The term may run more than once so
If blnRan Then Exit Sub 'just exit if it already ran
blnRan = True
On Error Resume Next
mColEmpty mcolOpenArg
Set mcolOpenArg = Nothing
End Sub
'*- Public Init/Terminate interface
'.-------------------------------------------------------------------------
'THESE FUNCTIONS SINK EVENTS DECLARED WITHEVENTS IN THIS CLASS '*+ Form
WithEvent interface
'*- Form WithEvent interface
'THESE FUNCTIONS / SUBS ARE USED TO IMPLEMENT CLASS FUNCTIONALITY '*+PRIVATE
Class function / sub declaration Private Function cOpenArg(strOpenArg As String)
As clsOpenArg Dim intPosEqual As Integer Dim strArgName As String Dim varArgVal
As Variant Dim lclsOpenArg As clsOpenArg
intPosEqual = InStr(strOpenArg, "=")
If intPosEqual > 0 Then
strArgName = Left$(strOpenArg, intPosEqual - 1)
varArgVal = Right$(strOpenArg, Len(strOpenArg) - intPosEqual)
Set lclsOpenArg = New clsOpenArg
lclsOpenArg.mInit strArgName, varArgVal
Set cOpenArg = lclsOpenArg
End If
End Function
'
Private Sub ParseOpenArgs()
Dim lstrOpenArgs As String
Dim strOpenArg As String
Dim intPos As Integer
Dim lclsOpenArg As clsOpenArg
lstrOpenArgs = mstrOpenArgs
intPos = InStr(lstrOpenArgs, ";")
While intPos > 0
strOpenArg = Left$(lstrOpenArgs, intPos - 1)
Set lclsOpenArg = OpenArg(strOpenArg)
mcolOpenArg.Add lclsOpenArg, lclsOpenArg.pName
lstrOpenArgs = Right$(lstrOpenArgs, Len(lstrOpenArgs) - intPos)
intPos = InStr(lstrOpenArgs, ";")
Wend
End Sub
'
'This function cycles through all the openargs applying them to form properties
'if an argument is named the same as a form property, and the property is
writeable '(doesn't require being in design view to set it) then the application
of the value 'to the property will be performed and Err will not be set. For
these OpenArgs we 'set the IsPrp to true '
'All of this provides a way for the developer to ppass in openargs to an opening
form 'which are then used to set form properties. It is up to the developer to
ensure that 'the property is settable, that the value they pass in is valid
(correct data type, 'correct value range etc.) '
'In the end, the only way to know whether a passed in OpenArg is a property is
to try 'it and see. If there is no error then the name is a property name, it
is settable in 'form view mode, and the value is acceptable.
'
Public Sub ApplyFrmProperties()
Dim lclsOpenArg As clsOpenArg
On Error Resume Next
For Each lclsOpenArg In mcolOpenArg
mfrm.Properties(lclsOpenArg.pName) = lclsOpenArg.pVal
lclsOpenArg.pIsPrp = (Err.Number = 0)
Err.Clear
Next lclsOpenArg
End Sub
'
'Empties out a collection containing class instances '
Public Function mColEmpty(col As Collection) On Error GoTo Err_mColEmpty
Dim obj As Object
On Error Resume Next
For Each obj In col
obj.mTerm
Next obj
On Error GoTo Err_mColEmpty
While col.Count > 0
col.Remove 1
Wend
exit_mColEmpty:
Exit Function
Err_mColEmpty:
Select Case Err
Case 91 'Collection empty
Resume exit_mColEmpty
Case Else
MsgBox Err.Description, , "Error in Function clsSysVars.mColEmpty"
Resume exit_mColEmpty
End Select
Resume 0 '.FOR TROUBLESHOOTING
End Function
'*-PRIVATE Class function / sub declaration '*+PUBLIC Class function / sub
declaration Function OpenArg(strArgName As String) As Variant On Error GoTo
Err_OpenArg
OpenArg = mcolOpenArg(strArgName).pVal
Exit_OpenArg:
Exit Function
Err_OpenArg:
Select Case Err
Case 91
MsgBox "OpenArg " & strArgName & " does not exist"
Resume Exit_OpenArg
Case Else
MsgBox Err.Description, , "Error in Function clsOpenArgs.OpenArg"
Resume Exit_OpenArg
End Select
Resume 0 '.FOR TROUBLESHOOTING
End Function'*-PUBLIC Class function / sub declaration
'===========================================================
'Form frmStates - a demo form that displays a state lookup table
'===========================================================
Option Compare Database
Option Explicit
Private lclsOpenArgs As clsOpenArgs
Private Sub Form_Open(Cancel As Integer)
Set lclsOpenArgs = New clsOpenArgs
lclsOpenArgs.mInit Me, True
End Sub
Private Sub cmdClose_Click()
On Error GoTo Err_cmdClose_Click
DoCmd.Close
Exit_cmdClose_Click:
Exit Sub
Err_cmdClose_Click:
MsgBox Err.Description
Resume Exit_cmdClose_Click
End Sub
'===========================================================
'Form frmOpenArgsDemo - a demo form that opens the state form, 'passing in
openargs '===========================================================
Option Compare Database
Option Explicit
Private Sub cmdStatesDataEntry_Click()
On Error GoTo Err_cmdStatesDataEntry_Click
Dim stDocName As String
Dim stLinkCriteria As String
Dim strOpenArgs As String
strOpenArgs = "DataEntry=True;AllowEdits=True;AllowDeletions=False;"
stDocName = "frmStates"
DoCmd.OpenForm stDocName, , , stLinkCriteria, , , strOpenArgs
Exit_cmdStatesDataEntry_Click:
Exit Sub
Err_cmdStatesDataEntry_Click:
MsgBox Err.Description
Resume Exit_cmdStatesDataEntry_Click
Resume 0
End Sub
John W. Colby
www.ColbyConsulting.com
-----Original Message-----
From: accessd-bounces at databaseadvisors.com
[mailto:accessd-bounces at databaseadvisors.com] On Behalf Of Darren DICK
Sent: Sunday, January 29, 2006 5:29 PM
To: 'Access Developers discussion and problem solving'
Subject: Re: [AccessD] Same form, different actions
Hi John
Anyone feel free to jump in if I have this wrong
The open Args are quite useful, but tacked on the end of a Do.cmd statement they
don't do much Just text or numbers (usually) tacked on the end of an OpenForm
Do.Cmd statment
The real 'power' is in the interpretation at the other end
.....
--
AccessD mailing list
AccessD at databaseadvisors.com
http://databaseadvisors.com/mailman/listinfo/accessd
Website: http://www.databaseadvisors.com