[AccessD] Multi-Instance Forms re-visited

Jim DeMarco Jdemarco at hudsonhealthplan.org
Thu Dec 16 14:53:52 CST 2004


Change BaseClassName to clsMultiForms (if my memory is correct).  The name of the class you're storing in the collection.

I believe Hwnd is unique as well.

Jim

-----Original Message-----
From: accessd-bounces at databaseadvisors.com
[mailto:accessd-bounces at databaseadvisors.com]On Behalf Of Francisco
Tapia
Sent: Thursday, December 16, 2004 3:10 PM
To: Access Developers discussion and problem solving
Subject: Re: [AccessD] Multi-Instance Forms re-visited


Thanks for all the help you've been giving me... I split my class in
to 2, the MultiForms class has the Form object along w/ the OpenArgs,
this is where I'll add the On Close Event so it removes the form from
the collection as well

please explain the name for BaseClassName?

since the i've split the classes I have

clsMultiForms which contains the Form, hWnd, OpenArgs (this one?)
then the clsMultiInstance (which contains the collection)

and I created a Public Variable on the module as well

I thought the hWnd was diffrent on each call... maybenot?

On Thu, 16 Dec 2004 08:29:01 -0500, Jim DeMarco
<Jdemarco at hudsonhealthplan.org> wrote:
> I don't see anything wrong with your call (I did see that someone correctly suggested a public or module level variable to hold your collection class object). Could it have anything to do with you instantiating an instance of your class from within itself (your Add method creates an object of the class type of which it is a member)?  I normally do this using two classes to keep the functionality separate, in this case one for the form object and its properties, another to handle collection duties (remember polymorphism and encapsulation?).
> 
> Your problem seems to be a duplicate key though.  Your original code appended a timestamp to the hwnd for use in the form's caption.  Maybe you should include that in the key as well to absolutely prevent a duplicate value.
> 
> BTW, it's also a good idea to add an Exists method to your collection class to avoid erroring out on duplicate keys:
> 
> Function Exists(strKey As String) As Boolean
> 'returns true if the key value (not index) exists in the collection
> Dim objTemp As BaseClassName 'if you use my original technique this would be your base clas object
> 
> On Error GoTo Exists_Err
> 
>     Set objTemp = m_PrivateCollection.Item(strKey) 'replace m_PrivateCollection w/ your module level collection object
>     Exists = True
> 
> Exit_Function:
>     Set objTemp = Nothing
>     Exit Function
> 
> Exists_Err:
>     If Err.Number = 5 Then
>         Exists = False
>     Else
>         'further error handling here for other error types
>         MsgBox "Error " & Err.Number & " " & Err.Description, vbOKOnly + vbExclamation, "Error"
>     End If
>     Resume Exit_Function
> End Function
> 
> Jim D.
> 
> -----Original Message-----
> From: accessd-bounces at databaseadvisors.com
> [mailto:accessd-bounces at databaseadvisors.com]On Behalf Of Francisco
> Tapia
> Sent: Wednesday, December 15, 2004 5:47 PM
> To: Access Developers discussion and problem solving
> Subject: Re: [AccessD] Multi-Instance Forms re-visited
> 
> This code works for displaying "one" form... but it does not give me a
> tolorance to opening a 2nd Form... :(, the original code worked fine
> for many forms... Ideas?
> 
> it could be the way that I'm calling it,  (such as
> 
> Dim MultiForms As clsMultiInstance
> 
>     If MultiForms Is Nothing Then
>         Set MultiForms = New clsMultiInstance
>     End If
>     MultiForms.Add frm, frm.hWnd, OpenArgs
> 
> ------------------------------
> VERSION 1.0 CLASS
> BEGIN
>   MultiUse = -1  'True
> END
> Attribute VB_Name = "clsMultiInstance"
> Attribute VB_GlobalNameSpace = False
> Attribute VB_Creatable = False
> Attribute VB_PredeclaredId = False
> Attribute VB_Exposed = False
> Option Compare Database
> 'Multi Instance Multiple Forms
> 
> Dim mForms As Collection
> Private colForm As Access.Form
> Private colhWnd As String
> Private colOpenArgs As String
> Public Property Let Form(frm As Access.Form)
>     Set colForm = frm
> End Property
> Public Property Get Form() As Access.Form
>     Set Form = colForm
> End Property
> Public Property Let hWnd(hWnd As String)
>     colhWnd = hWnd
> End Property
> Public Property Get strhWnd() As String
>     hWnd = colhWnd
> End Property
> Public Property Let OpenArgs(Args As String)
>     colOpenArgs = Args
> End Property
> Public Property Get OpenArgs() As String
>     OpenArgs = colOpenArgs
> End Property
> 
> Sub Add(frm As Access.Form, hWnd As String, OpenArgs As String,
> Optional Key As Variant)
> Dim x As clsMultiInstance
>        Set x = New clsMultiInstance
>        x.Form = frm
>        x.hWnd = hWnd
>        x.OpenArgs = OpenArgs
>        x.Form.Visible = True
> 
> 'On a 2nd call it errors out from here...
> ----> mForms.Add Item:=x, Key:=CStr(hWnd)
> 
> End Sub
> Sub Remove(hWnd As String)
>     'Purpose: Remove this instance from the collection.
>     Dim obj As Object           'Object in Collection
>     Dim blnRemove As Boolean    'Flag to remove it.
> 
>     'Check if this instance is in the collection.
>     '   (It won't be if form was opened directly, or code was reset.)
>     For Each obj In mForms
>         If obj.hWnd = hWnd Then
>             blnRemove = True
>             Exit For
>         End If
>     Next
>     'Deassign the object before removing from collection.
>     Set obj = Nothing
>     If blnRemove Then
>         mForms.Remove CStr(hWnd)
>     End If
> End Sub
> Function Count() As Integer
>     mForms.Count
> End Function
> Function Item(index As Variant) As clsMultiInstance
>    Set Item = mForms.Item(index)
> End Function
> Public Function Term()
>     'Purpose: Close all instances in the collection.
>     'Note: Leaves the copy opened directly from database window.
>     Dim lngKt As Long
>     Dim lngI As Long
> 
>     lngKt = mForms.Count
>     For lngI = 1 To lngKt
>         mForms.Remove 1
>     Next
>     Set mForms = Nothing
> End Function
> 
> Private Sub Class_Initialize()
> Set mForms = New Collection
> End Sub
> 
> ---------------END CLASS----------
> 
> On Wed, 15 Dec 2004 16:09:15 -0500, Jim DeMarco
> <Jdemarco at hudsonhealthplan.org> wrote:
> > Makes sense.  I was typing from (lack of) memory!!
> >
> > Hope it works out.
> >
> > Jim
> >
> > -----Original Message-----
> > From: accessd-bounces at databaseadvisors.com
> > [mailto:accessd-bounces at databaseadvisors.com]On Behalf Of Francisco
> > Tapia
> > Sent: Wednesday, December 15, 2004 4:03 PM
> > To: Access Developers discussion and problem solving
> > Subject: Re: [AccessD] Multi-Instance Forms re-visited
> >
> > Jim that sounds great (re: more code :D),
> >
> > I was wondering on this line:
> >
> > m_col.add(x,hWnd)
> >
> > access complains about an '='
> > so I re-wrote it as m_col.add x, hWnd
> >
> > On Wed, 15 Dec 2004 15:40:05 -0500, Jim DeMarco
> > <Jdemarco at hudsonhealthplan.org> wrote:
> > > Francisco,
> > >
> > > What about writing the value you want to use as openargs to an xml file and reading it in after the form is open?
> > >
> > > Or instead of a standard collection use a custom collection class that is similar to the one you have here but it would hold the form refernce, the form's hwind, and the openarg value.
> > >
> > > First a class to hold the data you're trying to use:
> > >
> > > 'MyClass
> > > <classStub>
> > > Public Property Let Form(frm as Access.Form)...
> > > Public Property Let hWnd(hWnd as String)...
> > > Public Property Let OpenArgs(Args As String)...
> > > </classStub>
> > >
> > > <collectionclassmodule>
> > > dim m_col as Collection
> > >
> > > 'MyCollectionClass
> > > Sub Add(frm As Access.Form, hWnd as String, OpenArgs as String, Optional Key As Variant)
> > > dim x as MyClass
> > > Sex x = new MyClass
> > >         x.Form = frm
> > >         x.hWnd = hWnd
> > >         x.OpenArgs = OpenArgs
> > >         m_col.add(x,hWnd)
> > > End Sub
> > >
> > > Function Item(index As Variant) As MyClass
> > >     Set Item = m_col.Item(index)
> > > End Function
> > > </collectionclassmodule>
> > >
> > > Now you've got access in your collection to all the info you need for your form.
> > > To store the values
> > > <snip>
> > > Dim MyCol as MyCollectionClass
> > >
> > >         MyCol.Add(frm, frm.Hwnd, "value1;value2))
> > > </snip>
> > >
> > > To retrieve them:
> > > <snip>
> > > Dim MyStringArg As String
> > >         MyStringArg = MyCol.Item(frm.hwnd).OpenArgs
> > >         'do something with MyStringArg
> > >
> > > </snip>
> > >
> > > It's really not as complicated as it might look. If you need more info or my complete custom collection class stub (VB) let me know.
> > >
> > > HTH,
> > >
> > > Jim DeMarco
> > >
> > > -----Original Message-----
> > > From: accessd-bounces at databaseadvisors.com
> > > [mailto:accessd-bounces at databaseadvisors.com]On Behalf Of Francisco
> > > Tapia
> > > Sent: Wednesday, December 15, 2004 1:40 PM
> > > To: Access Developers discussion and problem solving
> > > Subject: [AccessD] Multi-Instance Forms re-visited
> > >
> > > So I have the following code in a public module..
> > >
> > > the purpose is to have more than one instance of the form where end
> > > users can start "multiple calls" and then keep starting newer calls.
> > >
> > > the following code works really well and in fact I can do what I need
> > > with it, except passing openargs... I figure I can use a workaround
> > > unless someone here knows of a better way?
> > >
> > > thanks,
> > >
> > > ---CODE SNIP------------
> > > Option Compare Database
> > > Option Explicit
> > > 'Author:    Allen J Browne, January 2000
> > > 'Email:     abrowne at odyssey.apana.org.au
> > >
> > > Public clnClient As New Collection  'Instances of frmClient.
> > >
> > > Function OpenAClient()
> > >     'Purpose:   Open an independent instance of form frmClient.
> > >     Dim frm As Form
> > >
> > >     'Open a new instance, show it, and set a caption.
> > >     Set frm = New Form_frmClient
> > >     frm.Visible = True
> > >     frm.Caption = frm.Hwnd & ", opened " & Now()
> > >
> > >     'Append it to our collection.
> > >     clnClient.Add Item:=frm, Key:=CStr(frm.Hwnd)
> > >     Set frm = Nothing
> > > End Function
> > >
> > > Function CloseAllClients()
> > >     'Purpose: Close all instances in the clnClient collection.
> > >     'Note: Leaves the copy opened directly from database window.
> > >     Dim lngKt As Long
> > >     Dim lngI As Long
> > >
> > >     lngKt = clnClient.Count
> > >     For lngI = 1 To lngKt
> > >         clnClient.Remove 1
> > >     Next
> > > End Function
> > > ---END CODE SNIP-----------------
> > --
> --
> -Francisco
> http://pcthis.blogspot.com | PC news with out the jargon!
> --
> AccessD mailing list
> AccessD at databaseadvisors.com
> http://databaseadvisors.com/mailman/listinfo/accessd
> Website: http://www.databaseadvisors.com
> 
> ***********************************************************************************
> "This electronic message is intended to be for the use only of the named recipient, and may contain information from Hudson Health Plan (HHP) that is confidential or privileged.  If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution or use of the contents of this message is strictly prohibited.  If you have received this message in error or are not the named recipient, please notify us immediately, either by contacting the sender at the electronic mail address noted above or calling HHP at (914) 631-1611. If you are not the intended recipient, please do not forward this email to anyone, and delete and destroy all copies of this message.  Thank You".
> ***********************************************************************************
> 
> --
> AccessD mailing list
> AccessD at databaseadvisors.com
> http://databaseadvisors.com/mailman/listinfo/accessd
> Website: http://www.databaseadvisors.com
> 


-- 
-Francisco
http://pcthis.blogspot.com | PC news with out the jargon!
-- 
AccessD mailing list
AccessD at databaseadvisors.com
http://databaseadvisors.com/mailman/listinfo/accessd
Website: http://www.databaseadvisors.com


 



***********************************************************************************
"This electronic message is intended to be for the use only of the named recipient, and may contain information from Hudson Health Plan (HHP) that is confidential or privileged.  If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution or use of the contents of this message is strictly prohibited.  If you have received this message in error or are not the named recipient, please notify us immediately, either by contacting the sender at the electronic mail address noted above or calling HHP at (914) 631-1611. If you are not the intended recipient, please do not forward this email to anyone, and delete and destroy all copies of this message.  Thank You".
***********************************************************************************




More information about the AccessD mailing list