Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Public variable hiding from me in module procedures 1

Status
Not open for further replies.
Jul 24, 2000
88
CA
In my Access XP forms, I defined a Public variable in the declarations section of my form module (immediately following the Options Compare Database command) but found that its visibility was inconsistent within procedures in that module. In one procedure, I assign a value to it but in another procedure the variable is displayed in the debugger as <out of context>. I trace the assignment of the value with the debugger but when I watch the variable, it remains as <out of context). Does anyone have any ideas?

I have tried moving the Public declaration to the 'Global Code' module, but it makes no difference.

Thanks for your help.
RjB
 
A form is an object. Therefore, declaring a Public variable in the declarations section of a form is making that variable a public property of the form object. It can be accessed directly from within the object, but any references from outside of the form require a fully qualified object reference, such as {Forms]![frmName].PublicPropertyVariable.

I am somewhat confused by your last statement, because the place to declare a global variable is within the declarations section (again immediately after your Option statement and before the first routine) of a standard code module, again using the Public keyword, and not Dim.



Good Luck
--------------
To get the most from your Tek-Tips experience, please read FAQ181-2886
As a circle of light increases so does the circumference of darkness around it. - Albert Einstein
 
Thanks for your speedy response CC. I can see that if I wanted to reference a public in a module other than that in which it was defined I would need to prefix the usage with the object name. Thanks for that, I hadn't thought of it, but seems obvious now that you say it. However, my public was defined in the same module so I would have thought that an object prefix was uneccessary. I'll give it a try (using the module prefix) - it would not hunt to fully specify all variable that are defined outside of the procedure anyway.

Thanks again.
 
I can see that if I wanted to reference a public in a module an object other than that in which it was defined ..."

Forms, Reports, and Classes are objects. All variables declared within the declarations sections of Objects, are properties of the object, and their scope is the entire object. However, an object may expose one or more of its properties (and its methods) by using the keyword Public instead of Dim for properties, and Public in lieu of Private for methods) to the rest of the application. In order to use these properties/methods outside of the object, they must be preferenced with a fully qualified object reference.

Code Modules are NOT objects.

If you define a variable in the declarations section of the module, using Dim, then the scope of that variable in the entire module. If you define a variable in the declarations section with keyword Public, then the scope of the variable is global.

If you code is not behaving in accordance with the above description, then please post the code, and provide a description of how it is behaving.

Good Luck
--------------
To get the most from your Tek-Tips experience, please read FAQ181-2886
As a circle of light increases so does the circumference of darkness around it. - Albert Einstein
 
Thanks for your patience CC. I follow what you are saying about objects and believe I am, in this instance, dealing with a single object - that is my [Form_Projects Form] object.

Here are the snippets of my code that relate to the offending Public. I have prefixed the sections with some notes indicated with ***:

*** The following code declaring npPrg_ID is located at the beginning of the [Form_Projects Form] code:-

Option Compare Database
'=========================='
' Define some Publics'
'=========================='
Public npPrg_ID As Long


... Other Private Subs ...


*** The following code fires when the Program name is changed and when I 'watch' [Form_Projects Form].npPrg_ID, it takes the correct value.

'=========================='
Private Sub Prg_Name_Change()
'=========================='
On Error GoTo Err_Prg_Name_Change
Dim conMan As ADODB.Connection
Dim rstMan As ADODB.Recordset
Dim strFindArg As String

'***************************************'
' A new Program Name has been selected '
'***************************************'

' Retrieve Program Row:-
Set conMan = CurrentProject.Connection
Set rstMan = New ADODB.Recordset
With rstMan
.ActiveConnection = conMan
.CursorType = adOpenKeyset
.LockType = adLockPessimistic
.CursorLocation = adUseClient
.Open "Prg", , , , adCmdTable
strFindArg = "Name = '" + Prg_Name + "'"
.Find (strFindArg)
End With
Prg_Description = rstMan("Description")
[Form_Projects Form].npPrg_ID = rstMan("Prg ID") ' ***Value correctly assigned to Public

Exit_Prg_Name_Change:
rstMan.Close
Exit Sub

Err_Prg_Name_Change:
MsgBox Err.Description
Resume Exit_Prg_Name_Change

End Sub

... Other Private Subs ...


*** The following code fires when the user chooses to add a new project (the business rule here is that a Program must have been defined for a new project). When I look at the 'watched' value of [Form_Projects Form].npPrg_ID, its value is <out of context>. The context given for the 'watch' variable is "Form_Projects Form.Prg_Name_Change". I would have thought it would have been simply "Form_Projects Form" since it was defined as a public in the declarations section. I am puzzled???

'=========================='
Private Sub bNewPrj_Click()
'=========================='
On Error GoTo Err_bNewPrj_Click
Dim cPrj_ID As String
Dim conMan As ADODB.Command
Dim strSQL As String
Dim rstMan As New ADODB.Recordset


'***********************************************'
' Ensure a Program is defined for this Project '
'***********************************************'
If [Form_Projects Form].npPrg_ID = Null Then
MsgBox ("You must select a Program before you can add a new Project!")
Resume Exit_bNewPrj_Click
End If

If [Form_Projects Form].npPrg_ID = 0 Then
MsgBox ("You must select a Program before you can add a new Project!")
Resume Exit_bNewPrj_Click
End If

*************

I hope this extract is clear for you. I don't know how to include code snippets any other way.

Thanks for your help.

RjB
 
The IDE watch window always seems to use the current routine as the context. You will need to add a watch inside of each subroutine to fully monitor the behavior of a public property. Or you might try to set the watch expression to a fully qualified reference to the property. That might work. The IDE is not aware of the full scope of all variables. That's a problem with the watch window, not the application. The watch window has trouble with references inside of With statements as well.

Whenever you reference npPrg_ID within the methods and events of the form in which it's declared, you do not need the object reference.

If npPrg_ID = 0 Then

is fine if you're still inside the same instance of the same object.



Good Luck
--------------
To get the most from your Tek-Tips experience, please read FAQ181-2886
As a circle of light increases so does the circumference of darkness around it. - Albert Einstein
 
Hi CC.

When I started using this Public, I did not fully qualify it with the object name - I am doing that now just for clarity and to highlight Public variables.

I did add a watch inside the procedure/subroutine and noted that it had a different value to the fuly qualified one. Let me re-check what's going on and get back to you.

Thanks.
 
Hi again CC.

Well, it seems that fully qualifying publics (as I started to do yesterday) whenever they are used does the trick. I put a message box in the code and used that as a watch and now the Public seems to be getting the right values and is accessible in all procedures/subroutines.

As I said earlier, I do not mind fully qualifying my usage of Publics because it adds clarity to the code and I do not have too many of them - at least, not yet.

Thanks for all you wise councel and help.

RjB
 
You're quite welcome.

Good Luck
--------------
To get the most from your Tek-Tips experience, please read FAQ181-2886
As a circle of light increases so does the circumference of darkness around it. - Albert Einstein
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top