Link to home
Start Free TrialLog in
Avatar of mdanny
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?
Avatar of mcrider
mcrider

The only way to do that is to watch the variable with a timer... Sorry...

P.S. Don't shoot the messenger (with a bad grade)

Cheers!
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.
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
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


In your VB module, you now do not have to declare any global variables, except for one:

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.GlobalVariable1 = "hello"

End Sub

Private Sub Command3_Click()

'Oh, this user is trying to be clever. But it won't work!
Set gobjGlobals = Nothing
gobjGlobals.GlobalVariable1 = "world"

End Sub
Avatar of Éric Moreau
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).
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.SomeGlobalVariable = SomeValue

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!
Avatar of mdanny

ASKER

caraf_g should have the points.Great idea!
ASKER CERTIFIED SOLUTION
Avatar of caraf_g
caraf_g

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
caraf_g

t'was a question not an answer...

Wayne
Why a "B"?