mdanny
asked on
Fixed variables in VB
Can I initialize global variable ones
and then throw an error any time any
function in any part of a project
attempts to change it?
and then throw an error any time any
function in any part of a project
attempts to change it?
Yes it is possible, but you have to come away from the idea of global variables a little bit, and start using a little bit of the VB "Object Oriented" approach.
If you want to do that, let me know and I'll give you an example.
If you want to do that, let me know and I'll give you an example.
Could you use a constant and that way it never changes or are you looking to get the error so you act on it?
Public Const x = y
Public Const x = y
Juilette, I think mdanny wants to be able to set the global variable(s) to any value, once. Which can't be done with a constant.
Righty-o, here we go.
Instead of your global variables, we create a class module. This is an example of such a class module:
(Project - Add - Class Module. Call it clsGlobals)
Option Explicit
Private mblnGlobalVariable1Set As Boolean
Private mstrGlobalVariable1 As String
Public Property Let GlobalVariable1(NewValue As String)
If Not mblnGlobalVariable1Set Then
mstrGlobalVariable1 = NewValue
mblnGlobalVariable1Set = True
Else
Err.Raise 50001, , "You can't set this variable more than once!"
End If
End Property
Public Property Get GlobalVariable1() As String
GlobalVariable1 = mstrGlobalVariable1
End Property
Private Sub Class_Terminate()
Err.Raise 50002, , "O no you don't you sneaky person you. Trying to create a new one are we?"
End Sub
You can add as many "global variables" as you like. Just make sure that for each one you create the two private variables, the public property let and get procedures as above with GlobalVariable1
Instead of your global variables, we create a class module. This is an example of such a class module:
(Project - Add - Class Module. Call it clsGlobals)
Option Explicit
Private mblnGlobalVariable1Set As Boolean
Private mstrGlobalVariable1 As String
Public Property Let GlobalVariable1(NewValue As String)
If Not mblnGlobalVariable1Set Then
mstrGlobalVariable1 = NewValue
mblnGlobalVariable1Set = True
Else
Err.Raise 50001, , "You can't set this variable more than once!"
End If
End Property
Public Property Get GlobalVariable1() As String
GlobalVariable1 = mstrGlobalVariable1
End Property
Private Sub Class_Terminate()
Err.Raise 50002, , "O no you don't you sneaky person you. Trying to create a new one are we?"
End Sub
You can add as many "global variables" as you like. Just make sure that for each one you create the two private variables, the public property let and get procedures as above with GlobalVariable1
In your VB module, you now do not have to declare any global variables, except for one:
Option Explicit
Global gobjGlobals As New clsGlobals
Option Explicit
Global gobjGlobals As New clsGlobals
'''And this could be stuff you'd find in a user's Form module
Option Explicit
Private Sub Command1_Click()
'If this command button is clicked a second time, it will _
throw an error message. You can only set the variable once!
gobjGlobals.GlobalVariable 1 = "hello"
End Sub
Private Sub Command3_Click()
'Oh, this user is trying to be clever. But it won't work!
Set gobjGlobals = Nothing
gobjGlobals.GlobalVariable 1 = "world"
End Sub
Option Explicit
Private Sub Command1_Click()
'If this command button is clicked a second time, it will _
throw an error message. You can only set the variable once!
gobjGlobals.GlobalVariable
End Sub
Private Sub Command3_Click()
'Oh, this user is trying to be clever. But it won't work!
Set gobjGlobals = Nothing
gobjGlobals.GlobalVariable
End Sub
Build a public property instead of a public variable. Since you can put code in property procedures, you can raise error.
Property procedures can be placed in a standard module.
Public Property Get test() As Integer
MsgBox "getting test property"
End Property
Public Property Let test(ByVal vNewValue As Integer)
MsgBox "setting test property " & vNewValue
Err.Raise 1,"source","message"
End Property
The real fun with it is that you can set your Let property to private so that only the module in which the property appears will be able to put a new value in it (read-only to the rest of the project).
Property procedures can be placed in a standard module.
Public Property Get test() As Integer
MsgBox "getting test property"
End Property
Public Property Let test(ByVal vNewValue As Integer)
MsgBox "setting test property " & vNewValue
Err.Raise 1,"source","message"
End Property
The real fun with it is that you can set your Let property to private so that only the module in which the property appears will be able to put a new value in it (read-only to the rest of the project).
Only drawback is that where you used to be able to use a global variable simply as follows
SomeGlobalVariable = SomeValue
you now have to use an object variable and the dot notation
gobjGlobals.SomeGlobalVari able = SomeValue
That's the tradeoff for this solution.
SomeGlobalVariable = SomeValue
you now have to use an object variable and the dot notation
gobjGlobals.SomeGlobalVari
That's the tradeoff for this solution.
emoreau - you can even leave out the property Let procedure altogether ;-)
Cool, emoreau. I didn't realise you could use Property procedures in ordinary .bas modules !
mdanny - that would allow you to bypass the need for the object variable altogether!
mdanny - that would allow you to bypass the need for the object variable altogether!
ASKER
caraf_g should have the points.Great idea!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
caraf_g
t'was a question not an answer...
Wayne
t'was a question not an answer...
Wayne
Why a "B"?
P.S. Don't shoot the messenger (with a bad grade)
Cheers!