PC Review


Reply
 
 
JimS
Guest
Posts: n/a
 
      13th Jul 2009
I developed a class module in A2007. As I went along, I would instantiate it
each time I needed it ("dim oBoM as new clsBillofMaterial"), then set it to
nothing when I was done with it, typically at the beginning and end of an
event procedure. Then, I thought, "why re-instantiate it so often...why not
instantiate it in the opening declarations for a form where I might use it,
then use it as needed.

Well, I'm gettting all balled up in scope issues. Am I doing this right?
What's the approach?

--
Jim
 
Reply With Quote
 
 
 
 
Jack Leach
Guest
Posts: n/a
 
      13th Jul 2009
Stephen Lebans has a calendar class that is set on form opening and unloaded
on form closing. Here's a link to the site, which at about 3/4 the way down
the page explains where to put the various calls and declarations to have it
work (the class is loaded on form load and unloaded on the form's unload).

http://www.lebans.com/monthcalendar.htm

Here's a very condensed version:


Option Compare Database
Option Explicit

'Declare the Class
Private mc As clsMonthCal

'the form's Load event
Private Sub Form_Load()
Set mc = New clsMonthCal
End Sub

'the form's unload event (minus some safeguards...)
Private Sub Form_Unload(Cancel As Integer)
Set mc = Nothing
End Sub


Then call mc.whatever from anywhere in the form you want to use it.

hth


--
Jack Leach
www.tristatemachine.com

"I haven't failed, I've found ten thousand ways that don't work."
-Thomas Edison (1847-1931)



"JimS" wrote:

> I developed a class module in A2007. As I went along, I would instantiate it
> each time I needed it ("dim oBoM as new clsBillofMaterial"), then set it to
> nothing when I was done with it, typically at the beginning and end of an
> event procedure. Then, I thought, "why re-instantiate it so often...why not
> instantiate it in the opening declarations for a form where I might use it,
> then use it as needed.
>
> Well, I'm gettting all balled up in scope issues. Am I doing this right?
> What's the approach?
>
> --
> Jim

 
Reply With Quote
 
Albert D. Kallal
Guest
Posts: n/a
 
      14th Jul 2009
"JimS" <(E-Mail Removed)> wrote in message
news:77CE4153-C0B6-4473-88D4-(E-Mail Removed)...
>I developed a class module in A2007. As I went along, I would instantiate
>it
> each time I needed it ("dim oBoM as new clsBillofMaterial"), then set it
> to
> nothing when I was done with it, typically at the beginning and end of an
> event procedure. Then, I thought, "why re-instantiate it so often...why
> not
> instantiate it in the opening declarations for a form where I might use
> it,
> then use it as needed.
>
> Well, I'm gettting all balled up in scope issues. Am I doing this right?
> What's the approach?
>


I usually create and setup the class object in the forms load event.

However, often that object needs to be used in the next several forms that
will be opened.

So, you often see the following in my code:


clsBookInfo.MyClear ' setup class object
DoCmd.OpenForm "frmCalenderMain",,,,,,"Select date for event booking"

In form CalendarMain, you see in the defs:

Option Compare Database
Option Explicit

Public clsBookInfo As clsBooking
Dim frmPrevious As Form

Note how there is no new keyword used. I not going to instantiate a new
copy,
but I want the class object from the previous CALLING form.

So, my on-load code goes:


Set frmPrevious = Screen.ActiveForm
Set clsBookInfo = frmPrevious.clsBookInfo

Note how I now have a pointer to the previous class ojbect. Also, as a
codeing standard, I also pick up the previous form as per above. That way, I
cna have many differnt forms call this form, but on a close event I can go:

frmPrevious.Requery, etc.

In other words, I can access the prevous form as a varible.

And, when this form closes, all of the setup and use of the clbBookInfo
object is returned to the privous calling form. My applcaions will often go
2, 3 or even 4 forms deep using the above concepts... When the use finally
is done and starts closing the forms to get back where they came from, that
class objects values return back along for hte ride.

On the form when being closed, I can now call/execute code in the calling
form like:

frmPrevious.SelDoneB
DoCmd.Close acForm, Me.Name

SelDoneB is custom code in the calling form that needs to be run when I am
closign the current form. The nice part about using this approach is that I
don't have to make the form dialog (it is model, but not dialog).

The above desing also allows for multiplile instances of a form to be
opended...and the correct code from the calling (prevous) form is run when
using the above approach.

--
Albert D. Kallal (Access MVP)
Edmonton, Alberta Canada
(E-Mail Removed)



 
Reply With Quote
 
JimS
Guest
Posts: n/a
 
      14th Jul 2009
Hard to believe, but the code that failed yesterday works perfectly today. I
think I need to do the "decompile/compact/recompiile" thing to fix this
damned thing. Thanks so much for your answers. I'll study them for future
reference.

--
Jim


"JimBurke via AccessMonster.com" wrote:

> Whoops, where I put 'dim' meant 'public'.
>
> JimBurke wrote:
> >Make sure you have everything declared as public in the class module that
> >might be referenced anywhere outside of the class (I think - I'm not an OOP
> >expert). I would declare the class variable oBoM in a code module as public,
> >but without instantiating it, e.g.
> >
> >dim oBoM as clsBillofMaterial
> >
> >Actually if you only use it within that one form then you can declare the
> >variable as private in that form's code module (at the very top of it). If
> >you need to access it anywhere outside that form then declare it as public in
> >a separate code module.
> >
> >then wherever you want to instantiate it just set it:
> >
> >set oBoM = new clsBillofMaterial
> >
> >and set it to nothing as soon as you know you're done with it. without
> >knowing anything about your application or how the class is used I don't know
> >if you can just instantiate it once and keep using that, or when you might
> >have to declare a new instance, etc.
> >
> >>I developed a class module in A2007. As I went along, I would instantiate it
> >>each time I needed it ("dim oBoM as new clsBillofMaterial"), then set it to

> >[quoted text clipped - 5 lines]
> >>Well, I'm gettting all balled up in scope issues. Am I doing this right?
> >>What's the approach?

> >

>
> --
> Jim Burke
>
> Message posted via http://www.accessmonster.com
>
>

 
Reply With Quote
 
vanderghast
Guest
Posts: n/a
 
      14th Jul 2009
The variable you dim from the class is still a variable, and although the
data it indirectly refers to does not live on the stack, it is still a
variable and you should use its scope as usual: if you need it withih many
place in the form, declare it at the form level, and instanciate it in an
event firing once (for the life of the form), or test for its Nothing-ness
before using it and if Nothing, instance it or raise an assert (as you
expected it to be not nothing). If you only need it inside a given
procedure, then define and instance it inside the procedure. It is generally
not required to set it to nothing, from the program using the class object:
the variable going out of scope, or having the variable being re-assigned by
another object, will set the previous instance hold by the variable to
nothing for you.


Vanderghast, Access MVP

"JimS" <(E-Mail Removed)> wrote in message
news:77CE4153-C0B6-4473-88D4-(E-Mail Removed)...
>I developed a class module in A2007. As I went along, I would instantiate
>it
> each time I needed it ("dim oBoM as new clsBillofMaterial"), then set it
> to
> nothing when I was done with it, typically at the beginning and end of an
> event procedure. Then, I thought, "why re-instantiate it so often...why
> not
> instantiate it in the opening declarations for a form where I might use
> it,
> then use it as needed.
>
> Well, I'm gettting all balled up in scope issues. Am I doing this right?
> What's the approach?
>
> --
> Jim


 
Reply With Quote
 
JimS
Guest
Posts: n/a
 
      14th Jul 2009
Well, I'm still having issues...
I decompiled and recompiled, etc. per advice from another poster.
I get an error on the Me. filter= statement in btnAddNewNoM_Click() routine.
The error refers to oBoM as if it were uninstantiated. I trap it and
try to see a property of the class in the immediate window, and sure enough,
it's not there.

I have to believe this is some syntax issue.

' Start Code

Option Compare Database
Option Explicit
Dim HourlyRate As Currency
Dim NewBoMHeaderID As Long
Public oBoM As clsBillofMaterial

Private Sub btnAddEmpty_Click()
NewBoMHeaderID = oBoM.AddBoMHeader(Me.cbWOID)
Me.Filter = "tblBoM.BomID=" & NewBoMHeaderID
Me.FilterOn = True
Me.cbWOID.Requery
Me.cbWOID = ""
Me.tbWODesc = ""
End Sub

Private Sub btnAddNewBoM_Click()
Me.Filter = "BoMWOID=" & Me.cbWOID & " AND BoMSeq=0" &
CStr(oBoM.NextBoMSeq(Me.cbWOID))
DoCmd.OpenForm FormName:="popupCloneBoM", Openargs:=CStr(Me.cbWOID)

Me.FilterOn = True
End Sub

Private Sub btnDelete_Click()
oBoM.delete Me.BoMWOID, Me.BoMSeq
End Sub

Private Sub cbWOID_AfterUpdate()
Me.tbWODesc = Me.cbWOID.Column(2)
Me.tbWODesc.Requery
tbHourlyRate.Requery
Me.Filter = "BoMWOID=" & Me.cbWOID & " AND BoMSeq=0" & Me.cbWOID.Column(3)
Me.FilterOn = True
End Sub

Private Sub Form_BeforeUpdate(Cancel As Integer)
'Check here to make sure the new quantity is not less than the "picked"
quantity

End Sub

Private Sub Form_Close()
Set oBoM = Nothing
End Sub

Private Sub Form_Load()
HourlyRate = 0
Me.cbWOID = Me.cbWOID.ItemData(0)
Me.Filter = "BoMWOID=" & Me.cbWOID & " AND BoMSeq=0" & Me.cbWOID.Column(3)
Me.FilterOn = True
Me.tbWODesc = Me.cbWOID.Column(2)
End Sub

Private Sub Form_Open(Cancel As Integer)
Set oBoM = New clsBillofMaterial
End Sub

--
Jim


"vanderghast" wrote:

> The variable you dim from the class is still a variable, and although the
> data it indirectly refers to does not live on the stack, it is still a
> variable and you should use its scope as usual: if you need it withih many
> place in the form, declare it at the form level, and instanciate it in an
> event firing once (for the life of the form), or test for its Nothing-ness
> before using it and if Nothing, instance it or raise an assert (as you
> expected it to be not nothing). If you only need it inside a given
> procedure, then define and instance it inside the procedure. It is generally
> not required to set it to nothing, from the program using the class object:
> the variable going out of scope, or having the variable being re-assigned by
> another object, will set the previous instance hold by the variable to
> nothing for you.
>
>
> Vanderghast, Access MVP
>
> "JimS" <(E-Mail Removed)> wrote in message
> news:77CE4153-C0B6-4473-88D4-(E-Mail Removed)...
> >I developed a class module in A2007. As I went along, I would instantiate
> >it
> > each time I needed it ("dim oBoM as new clsBillofMaterial"), then set it
> > to
> > nothing when I was done with it, typically at the beginning and end of an
> > event procedure. Then, I thought, "why re-instantiate it so often...why
> > not
> > instantiate it in the opening declarations for a form where I might use
> > it,
> > then use it as needed.
> >
> > Well, I'm gettting all balled up in scope issues. Am I doing this right?
> > What's the approach?
> >
> > --
> > Jim

>

 
Reply With Quote
 
vanderghast
Guest
Posts: n/a
 
      14th Jul 2009
Your code defines the object oBoM at the form level (and being Public, can
be accessed by other VBA code, through the form object 'as if' it was some
new form property). If it is not required, leave it Private.

Your code created an objet oBoM in the form Open event, but does not seems
to initialize it. So, your object oBoM will have all its data set to default
values, unless your oBoM class Initialize event (in the code of
clsBillofmaterial class) does something to its internal data.

Add a break point at the line where your error occur, so just before the
error occurs. Then, once the code stops at the break point (and before
executing the line producing the error)

Check if Me.cbWOID has a not null value.

? Me.cbWOID IS NULL



if it is null, the method NextBoMSeq must have its first argument AS
VARIANT or AS OBJECT (preferably As Variant).
BUT your filter will be in error anyhow, since the concatenated strings
result will be something like:

"BoMWOID= AND BoMSeq=0"

which is not a valid filter (because ... BoMWOID is equal to ... what? )


Check if oBoM is NOT Nothing,

? oBoM IS Nothing


if it is nothing, you have to track where your code set it to nothing (since
the variable is public, that maybe from code living OUTSIDE your form; if
the object is private, only the code in your form, and in class
clsBillofMaterial, can set it to Nothing)

In the Locals window (View | Locals Window), check if your variable oBoM has
all the required properties/methods (and see if the values you can reach
make 'sense', if applicable).

In the immediate debug window, check if oBoM.NextBoMSeq(Me.cbWOID) returns
NOT a NULL value.

? oBoM.NextBoMSeq(Me.cbWOID) IS NULL

If it returns a NULL value, CSTR(Null) will err.
Also check it returns an integer.

? oBoM.NextBoMSeq(Me.cbWOID)

If it returns a string, then the filter become, after concatenation:

"BoMWOID= 44 AND BoMSeq = 0AAA"


as example, and the string has wrong delimiters, it should be:

"BoMWOID= 44 AND BoMSeq = '0AAA' "

or

"BoMWOID= 'B44' AND BoMSeq = '0AAA' "


as example (or something similar). Note that Me.cbWOID should return a
number, else your code need ALSO the proper delimiters for the value
filtering BoMWOID.


In the Immediate Debug Window, check if the concatenated strings result in
something valid for the filter:

? "BoMWOID=" & Me.cbWOID & " AND BoMSeq=0" &
CStr(oBoM.NextBoMSeq(Me.cbWOID))



Note that you can add a line in the Form_Open sub:

Private Sub Form_Open(Cancel As Integer)
Set oBoM = New clsBillofMaterial
Debug.Assert Not oBoM Is Nothing ' assume oBoM is not nothing
End Sub


since, after all, you Assert (assume) the object is not nothing, anymore, at
this point. You can also insert the same line of code as the first line of
code in btnAddNewBoM_Click( ), for the same reason.



And it can be that the problem is something else...



Vanderghast, Access MVP


"JimS" <(E-Mail Removed)> wrote in message
news:B277B67D-A42A-4708-BDEA-(E-Mail Removed)...
> Well, I'm still having issues...
> I decompiled and recompiled, etc. per advice from another poster.
> I get an error on the Me. filter= statement in btnAddNewNoM_Click()
> routine.
> The error refers to oBoM as if it were uninstantiated. I trap it and
> try to see a property of the class in the immediate window, and sure
> enough,
> it's not there.
>
> I have to believe this is some syntax issue.
>
> ' Start Code
>
> Option Compare Database
> Option Explicit
> Dim HourlyRate As Currency
> Dim NewBoMHeaderID As Long
> Public oBoM As clsBillofMaterial
>
> Private Sub btnAddEmpty_Click()
> NewBoMHeaderID = oBoM.AddBoMHeader(Me.cbWOID)
> Me.Filter = "tblBoM.BomID=" & NewBoMHeaderID
> Me.FilterOn = True
> Me.cbWOID.Requery
> Me.cbWOID = ""
> Me.tbWODesc = ""
> End Sub
>
> Private Sub btnAddNewBoM_Click()
> Me.Filter = "BoMWOID=" & Me.cbWOID & " AND BoMSeq=0" &
> CStr(oBoM.NextBoMSeq(Me.cbWOID))
> DoCmd.OpenForm FormName:="popupCloneBoM", Openargs:=CStr(Me.cbWOID)
>
> Me.FilterOn = True
> End Sub
>
> Private Sub btnDelete_Click()
> oBoM.delete Me.BoMWOID, Me.BoMSeq
> End Sub
>
> Private Sub cbWOID_AfterUpdate()
> Me.tbWODesc = Me.cbWOID.Column(2)
> Me.tbWODesc.Requery
> tbHourlyRate.Requery
> Me.Filter = "BoMWOID=" & Me.cbWOID & " AND BoMSeq=0" &
> Me.cbWOID.Column(3)
> Me.FilterOn = True
> End Sub
>
> Private Sub Form_BeforeUpdate(Cancel As Integer)
> 'Check here to make sure the new quantity is not less than the "picked"
> quantity
>
> End Sub
>
> Private Sub Form_Close()
> Set oBoM = Nothing
> End Sub
>
> Private Sub Form_Load()
> HourlyRate = 0
> Me.cbWOID = Me.cbWOID.ItemData(0)
> Me.Filter = "BoMWOID=" & Me.cbWOID & " AND BoMSeq=0" &
> Me.cbWOID.Column(3)
> Me.FilterOn = True
> Me.tbWODesc = Me.cbWOID.Column(2)
> End Sub
>
> Private Sub Form_Open(Cancel As Integer)
> Set oBoM = New clsBillofMaterial
> End Sub
>
> --
> Jim
>
>
> "vanderghast" wrote:
>
>> The variable you dim from the class is still a variable, and although the
>> data it indirectly refers to does not live on the stack, it is still a
>> variable and you should use its scope as usual: if you need it withih
>> many
>> place in the form, declare it at the form level, and instanciate it in an
>> event firing once (for the life of the form), or test for its
>> Nothing-ness
>> before using it and if Nothing, instance it or raise an assert (as you
>> expected it to be not nothing). If you only need it inside a given
>> procedure, then define and instance it inside the procedure. It is
>> generally
>> not required to set it to nothing, from the program using the class
>> object:
>> the variable going out of scope, or having the variable being re-assigned
>> by
>> another object, will set the previous instance hold by the variable to
>> nothing for you.
>>
>>
>> Vanderghast, Access MVP
>>
>> "JimS" <(E-Mail Removed)> wrote in message
>> news:77CE4153-C0B6-4473-88D4-(E-Mail Removed)...
>> >I developed a class module in A2007. As I went along, I would
>> >instantiate
>> >it
>> > each time I needed it ("dim oBoM as new clsBillofMaterial"), then set
>> > it
>> > to
>> > nothing when I was done with it, typically at the beginning and end of
>> > an
>> > event procedure. Then, I thought, "why re-instantiate it so often...why
>> > not
>> > instantiate it in the opening declarations for a form where I might use
>> > it,
>> > then use it as needed.
>> >
>> > Well, I'm gettting all balled up in scope issues. Am I doing this
>> > right?
>> > What's the approach?
>> >
>> > --
>> > Jim

>>


 
Reply With Quote
 
JimS
Guest
Posts: n/a
 
      14th Jul 2009
Thanks for the encouragement...

For what it's worth...my class has no initialization routine and no
termination routine (though I'm thinking of doing a debug.print "I've just
been instatiated"...

My class also has no properties, only events. For all intents and purposes,
it's a code module, but I wanted to practice class modules and I expect
eventually to add some properties and other goodies.

I'll run through your ideas and see what comes out...

Again, thanx!

Jim
--
Jim


"vanderghast" wrote:

> Your code defines the object oBoM at the form level (and being Public, can
> be accessed by other VBA code, through the form object 'as if' it was some
> new form property). If it is not required, leave it Private.
>
> Your code created an objet oBoM in the form Open event, but does not seems
> to initialize it. So, your object oBoM will have all its data set to default
> values, unless your oBoM class Initialize event (in the code of
> clsBillofmaterial class) does something to its internal data.
>
> Add a break point at the line where your error occur, so just before the
> error occurs. Then, once the code stops at the break point (and before
> executing the line producing the error)
>
> Check if Me.cbWOID has a not null value.
>
> ? Me.cbWOID IS NULL
>
>
>
> if it is null, the method NextBoMSeq must have its first argument AS
> VARIANT or AS OBJECT (preferably As Variant).
> BUT your filter will be in error anyhow, since the concatenated strings
> result will be something like:
>
> "BoMWOID= AND BoMSeq=0"
>
> which is not a valid filter (because ... BoMWOID is equal to ... what? )
>
>
> Check if oBoM is NOT Nothing,
>
> ? oBoM IS Nothing
>
>
> if it is nothing, you have to track where your code set it to nothing (since
> the variable is public, that maybe from code living OUTSIDE your form; if
> the object is private, only the code in your form, and in class
> clsBillofMaterial, can set it to Nothing)
>
> In the Locals window (View | Locals Window), check if your variable oBoM has
> all the required properties/methods (and see if the values you can reach
> make 'sense', if applicable).
>
> In the immediate debug window, check if oBoM.NextBoMSeq(Me.cbWOID) returns
> NOT a NULL value.
>
> ? oBoM.NextBoMSeq(Me.cbWOID) IS NULL
>
> If it returns a NULL value, CSTR(Null) will err.
> Also check it returns an integer.
>
> ? oBoM.NextBoMSeq(Me.cbWOID)
>
> If it returns a string, then the filter become, after concatenation:
>
> "BoMWOID= 44 AND BoMSeq = 0AAA"
>
>
> as example, and the string has wrong delimiters, it should be:
>
> "BoMWOID= 44 AND BoMSeq = '0AAA' "
>
> or
>
> "BoMWOID= 'B44' AND BoMSeq = '0AAA' "
>
>
> as example (or something similar). Note that Me.cbWOID should return a
> number, else your code need ALSO the proper delimiters for the value
> filtering BoMWOID.
>
>
> In the Immediate Debug Window, check if the concatenated strings result in
> something valid for the filter:
>
> ? "BoMWOID=" & Me.cbWOID & " AND BoMSeq=0" &
> CStr(oBoM.NextBoMSeq(Me.cbWOID))
>
>
>
> Note that you can add a line in the Form_Open sub:
>
> Private Sub Form_Open(Cancel As Integer)
> Set oBoM = New clsBillofMaterial
> Debug.Assert Not oBoM Is Nothing ' assume oBoM is not nothing
> End Sub
>
>
> since, after all, you Assert (assume) the object is not nothing, anymore, at
> this point. You can also insert the same line of code as the first line of
> code in btnAddNewBoM_Click( ), for the same reason.
>
>
>
> And it can be that the problem is something else...
>
>
>
> Vanderghast, Access MVP
>
>
> "JimS" <(E-Mail Removed)> wrote in message
> news:B277B67D-A42A-4708-BDEA-(E-Mail Removed)...
> > Well, I'm still having issues...
> > I decompiled and recompiled, etc. per advice from another poster.
> > I get an error on the Me. filter= statement in btnAddNewNoM_Click()
> > routine.
> > The error refers to oBoM as if it were uninstantiated. I trap it and
> > try to see a property of the class in the immediate window, and sure
> > enough,
> > it's not there.
> >
> > I have to believe this is some syntax issue.
> >
> > ' Start Code
> >
> > Option Compare Database
> > Option Explicit
> > Dim HourlyRate As Currency
> > Dim NewBoMHeaderID As Long
> > Public oBoM As clsBillofMaterial
> >
> > Private Sub btnAddEmpty_Click()
> > NewBoMHeaderID = oBoM.AddBoMHeader(Me.cbWOID)
> > Me.Filter = "tblBoM.BomID=" & NewBoMHeaderID
> > Me.FilterOn = True
> > Me.cbWOID.Requery
> > Me.cbWOID = ""
> > Me.tbWODesc = ""
> > End Sub
> >
> > Private Sub btnAddNewBoM_Click()
> > Me.Filter = "BoMWOID=" & Me.cbWOID & " AND BoMSeq=0" &
> > CStr(oBoM.NextBoMSeq(Me.cbWOID))
> > DoCmd.OpenForm FormName:="popupCloneBoM", Openargs:=CStr(Me.cbWOID)
> >
> > Me.FilterOn = True
> > End Sub
> >
> > Private Sub btnDelete_Click()
> > oBoM.delete Me.BoMWOID, Me.BoMSeq
> > End Sub
> >
> > Private Sub cbWOID_AfterUpdate()
> > Me.tbWODesc = Me.cbWOID.Column(2)
> > Me.tbWODesc.Requery
> > tbHourlyRate.Requery
> > Me.Filter = "BoMWOID=" & Me.cbWOID & " AND BoMSeq=0" &
> > Me.cbWOID.Column(3)
> > Me.FilterOn = True
> > End Sub
> >
> > Private Sub Form_BeforeUpdate(Cancel As Integer)
> > 'Check here to make sure the new quantity is not less than the "picked"
> > quantity
> >
> > End Sub
> >
> > Private Sub Form_Close()
> > Set oBoM = Nothing
> > End Sub
> >
> > Private Sub Form_Load()
> > HourlyRate = 0
> > Me.cbWOID = Me.cbWOID.ItemData(0)
> > Me.Filter = "BoMWOID=" & Me.cbWOID & " AND BoMSeq=0" &
> > Me.cbWOID.Column(3)
> > Me.FilterOn = True
> > Me.tbWODesc = Me.cbWOID.Column(2)
> > End Sub
> >
> > Private Sub Form_Open(Cancel As Integer)
> > Set oBoM = New clsBillofMaterial
> > End Sub
> >
> > --
> > Jim
> >
> >
> > "vanderghast" wrote:
> >
> >> The variable you dim from the class is still a variable, and although the
> >> data it indirectly refers to does not live on the stack, it is still a
> >> variable and you should use its scope as usual: if you need it withih
> >> many
> >> place in the form, declare it at the form level, and instanciate it in an
> >> event firing once (for the life of the form), or test for its
> >> Nothing-ness
> >> before using it and if Nothing, instance it or raise an assert (as you
> >> expected it to be not nothing). If you only need it inside a given
> >> procedure, then define and instance it inside the procedure. It is
> >> generally
> >> not required to set it to nothing, from the program using the class
> >> object:
> >> the variable going out of scope, or having the variable being re-assigned
> >> by
> >> another object, will set the previous instance hold by the variable to
> >> nothing for you.
> >>
> >>
> >> Vanderghast, Access MVP
> >>
> >> "JimS" <(E-Mail Removed)> wrote in message
> >> news:77CE4153-C0B6-4473-88D4-(E-Mail Removed)...
> >> >I developed a class module in A2007. As I went along, I would
> >> >instantiate
> >> >it
> >> > each time I needed it ("dim oBoM as new clsBillofMaterial"), then set
> >> > it
> >> > to
> >> > nothing when I was done with it, typically at the beginning and end of
> >> > an
> >> > event procedure. Then, I thought, "why re-instantiate it so often...why
> >> > not
> >> > instantiate it in the opening declarations for a form where I might use
> >> > it,
> >> > then use it as needed.
> >> >
> >> > Well, I'm gettting all balled up in scope issues. Am I doing this
> >> > right?
> >> > What's the approach?
> >> >
> >> > --
> >> > Jim
> >>

>

 
Reply With Quote
 
David W. Fenton
Guest
Posts: n/a
 
      14th Jul 2009
=?Utf-8?B?SmltUw==?= <(E-Mail Removed)> wrote in
news:77CE4153-C0B6-4473-88D4-(E-Mail Removed):

> I developed a class module in A2007. As I went along, I would
> instantiate it each time I needed it ("dim oBoM as new
> clsBillofMaterial"), then set it to nothing when I was done with
> it, typically at the beginning and end of an event procedure.
> Then, I thought, "why re-instantiate it so often...why not
> instantiate it in the opening declarations for a form where I
> might use it, then use it as needed.
>
> Well, I'm gettting all balled up in scope issues. Am I doing this
> right? What's the approach?


Instantiate the object according to its necessary scope.

Yes, that's no answer!

Remember that if you re-use an existing instance, it will retain the
properties that have been set in its previous life. One way to make
that easy is to have a method that resets all the properties to
their default values.

I tend to use class modules to share data between multiple contexts,
so I generally don't instantiate them as I go along, so much as I
have a global instance that initializes itself the first time it's
used. It's then up to me to track what values need to be reset or
not.

With a global variable declaration of the type you've been using in
private contexts:

Public oBoM As New clsBillofMaterial

the easiest possible way to re-initialize it is simply:

Set oBoM = Nothing

....and then immediately start setting properties of the public
instance (which will re-initialize it without you needing to have
code that resets any of the properties or members of the class
module).

The answer to your question:

It depends!

--
David W. Fenton http://www.dfenton.com/
usenet at dfenton dot com http://www.dfenton.com/DFA/
 
Reply With Quote
 
David W. Fenton
Guest
Posts: n/a
 
      14th Jul 2009
"Albert D. Kallal" <(E-Mail Removed)> wrote in
news:(E-Mail Removed):

> "JimS" <(E-Mail Removed)> wrote in message
> news:77CE4153-C0B6-4473-88D4-(E-Mail Removed)...
>>I developed a class module in A2007. As I went along, I would
>>instantiate it
>> each time I needed it ("dim oBoM as new clsBillofMaterial"), then
>> set it to
>> nothing when I was done with it, typically at the beginning and
>> end of an event procedure. Then, I thought, "why re-instantiate
>> it so often...why not
>> instantiate it in the opening declarations for a form where I
>> might use it,
>> then use it as needed.
>>
>> Well, I'm gettting all balled up in scope issues. Am I doing this
>> right? What's the approach?
>>

>
> I usually create and setup the class object in the forms load
> event.
>
> However, often that object needs to be used in the next several
> forms that will be opened.
>
> So, you often see the following in my code:
>
> clsBookInfo.MyClear ' setup class object
> DoCmd.OpenForm "frmCalenderMain",,,,,,"Select date for event
> booking"
>
> In form CalendarMain, you see in the defs:
>
> Option Compare Database
> Option Explicit
>
> Public clsBookInfo As clsBooking
> Dim frmPrevious As Form
>
> Note how there is no new keyword used. I not going to instantiate
> a new copy,
> but I want the class object from the previous CALLING form.


But within the context of CalendarMain's class module, you'll be
using Forms!CalendarMain.clsBookInfo, which is not the same instance
as the one referred to in the line immediately before you open the
form CalendarMain. You have an overlap in terms of the name of your
class module instance's variable name.

> So, my on-load code goes:
>
> Set frmPrevious = Screen.ActiveForm
> Set clsBookInfo = frmPrevious.clsBookInfo
>
> Note how I now have a pointer to the previous class ojbect.


Now, that's a different story. In this case you're using the same
class instance, because it's a public member of the class module of
the other form, and you're assured that it's the same class
instance.

But in your original example, you operated on one instance of the
class module:

Instance 1: clsBookInfo.MyClear ' setup class object

Then opened a form:

DoCmd.OpenForm "frmCalenderMain", , , , , , _
"Select date for event booking"

And in that form's class module, initiated an entirely new instance
of the your base class:

Instance 2: Public clsBookInfo As clsBooking

This is because you have a local variable declaration in your
newly-opened form. If you want to use the same instance, then either
do what you said later (use an instance that is exposed as a public
member of another form's class module), or use an instance that is
defined as a public variable.

Quibbling aside in regard to your bollixed presentation of what you
are recommending, your approach is very good and quite useful.

--
David W. Fenton http://www.dfenton.com/
usenet at dfenton dot com http://www.dfenton.com/DFA/
 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Scope of class data Hoop Microsoft C# .NET 2 20th Feb 2008 05:19 PM
Re: Class Module Scope Ed Adamthwaite Microsoft Access VBA Modules 0 12th Jan 2007 03:46 AM
Class scope =?Utf-8?B?TWljaGFlbA==?= Microsoft C# .NET 2 19th Jul 2006 05:15 PM
ADSI returning groups in Global scope and Domain local scope instead of Universal scope Maziar Aflatoun Microsoft C# .NET 1 21st Apr 2004 04:08 PM
Class's Scope JJ Microsoft C# .NET 2 2nd Feb 2004 07:44 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 12:21 AM.