Declaring public variables

confusion123

Active Member
Joined
Jul 27, 2014
Messages
400
Is it good practice NOT to declare variables publically but instead define a class?

So in place of this in a standard module:

Code:
Public FileNumber As Integer

use this in MyClass

Code:
Private mintFileNumber As Integer

Public Property Get FileNumber() As Integer

    FileNumber = mintFileNumber

End Property

Public Property Let FileNumber(ByVal FNumber As Integer)

    mintFileNumber = FNumber

End Property

but I still need to add this in a standard module:

Code:
Global MyFileNumber As MyClass

Thanks
 

Excel Facts

How to create a cell-sized chart?
Tiny charts, called Sparklines, were added to Excel 2010. Look for Sparklines on the Insert tab.
Generally, yes, though you'd use Public, not Global (it's a legacy term from older versions).

The reason is that it's inherently safer, it's much easier to accidentally change FileNumber than MyFileNumber.FileNumber. It also means that you reduce the amount of required public variables to 1 class that contains them.
 
Upvote 0
You can also create (to all intents and purposes) a static class by setting the VB_PredeclaredId attribute to True (you need to do this in a text editor, it's not available in the IDE). This makes your class methods accessible publicly without instantiating an instance of the class and having to create a public variable for it. - Just like userforms
 
  • Like
Reactions: shg
Upvote 0
You can also create (to all intents and purposes) a static class by setting the VB_PredeclaredId attribute to True (you need to do this in a text editor, it's not available in the IDE). This makes your class methods accessible publicly without instantiating an instance of the class and having to create a public variable for it. - Just like userforms

Thanks, never knew that.

What's your view on neither publically declaring nor using classes but simply passing arguments?

For example in module1 I have:

Code:
Dim FileNumber As Integer ' declared at the procedure level

then if I want to use it in module2, I write:

Code:
Sub MySub(MyFile As Integer)

Is that preferable?
 
Last edited:
Upvote 0
... by setting the VB_PredeclaredId attribute to True (you need to do this in a text editor, ...
I didn't know that either -- thanks, Kyle. Is that essentially auto-instancing?
 
Upvote 0
Yes. It's the way it's done with the UserForms, there's a description of it here [MS-VBAL]: Default Instance Variables Static Semantics. I tend not to use the auto instanced userforms but this method is quite nice for public variables/contstants. It is also useful since it allows a handy method of creating a public singleton, consider:

Globals

Code:
Private Sub Class_Initialize()
    Debug.Print "I am only called Once"
End Sub
Public Property Get MyName()
    MyName = "Kyle"
End Property

Code:
Sub test()
    Debug.Print Globals.MyName
    test2
End Sub


Sub test2()
    Debug.Print Globals.MyName
End Sub

@con123, yes, passing parameters is preferable. In general it's best to keep scope as limited as possible
 
Last edited:
Upvote 0
Your edit partially answers the question I was about to ask as to why this would be a good thing, but for me it would always have the same problem as using the auto-instance of a userform, wouldn't it?
 
Last edited:
Upvote 0
Yes, you'd have the same issues as a userform auto instance, but they are slightly different things. A class like this would likely exist for the entirety of the runtime, userforms typically don't so more control over their creation/destruction is warranted.

Of course this is nothing that cannot be achieved by instancing in the normal way, it just removes the need for a constructor function and you only want a single instance of a singleton by its definition.
 
Last edited:
Upvote 0
I think the issue of not being able to detect a reset (say due to state loss) would rule it out for me. Shame since otherwise you could store a Ribbon handle in it.
 
Upvote 0
Never having done anything with the ribbon, I don't get the reference. You'd typically use a pattern like this for something like a logging object that is called from many places in the application and controls access to a single resource. It doesn't really offer anything that you can't do with a simple constructor function though:
Code:
Private p_Globals As Globals


Public Function myGlobals() As Globals
    If p_Globals Is Nothing Then Set p_Globals = New Globals
    Set myGlobals = p_Globals
End Function
 
Upvote 0

Forum statistics

Threads
1,214,665
Messages
6,120,804
Members
448,990
Latest member
rohitsomani

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top