Declaring adn defininf public variables (1 Viewer)

chrisjames25

Registered User.
Local time
Today, 23:03
Joined
Dec 1, 2014
Messages
401
Hi

NIce and simple one for the forum i think.

If i want to declare some variables that i can then reference within the whole vba code for a particular form how do i do it?

At moment i am doing

Code:
Public StrTier1, StrTier11  As String
StrTier1 = "Category"
StrTier11 = "category"

However it is not defining the variable for me.

I get very confused with naming conventions, but i want these to be available for the whole of a form but not be used outside the form so do they need to be public or can then be private. If private how do i define them so not associated with only one event of the form.
 

jdraw

Super Moderator
Staff member
Local time
Today, 19:03
Joined
Jan 23, 2006
Messages
15,364
In plain English, using terms you would use when taking to a 6 year old, please describe to readers what you are trying to accomplish. No jargon, no quasi database terms.

In Access you must explicitly dim variables:

Dim str1 as String
Dim str2 as String
or
Dim str1 as string, str2 as string

Some info on Global, Public, Private

More info
 

jleach

Registered User.
Local time
Today, 19:03
Joined
Jan 4, 2012
Messages
308
In VBA there's (essentially) three different variable scopes that can be used:

1) Procedure level: this is the most common, where the variable is defined (dimmed) within the procedure, and is not visible outside the procedure
2) "Private" or "Module" level scope, which is where the variable is declared at the top of the module and is visible to all code within that module, but not outside the module. This is done via "Private x As Long" before any procedures within a module.
3) "Public" scope, which is available to all code within the module, as well as all code outside of the module (more or less... close enough of gov't work). This is done by declaring a module as "Public" or "Global" at the module level (ie, before any procedures in the module).

Code:
Option Compare Database
Option Explicit

' available to all code
Public MyPublicVariable As String

' available to all code in this module
Private MyModuleLevelVariable As String

'start of procedures/end of module declaration area
Private Function DoStuff()
  Dim x As Long  'only available to this function
  ...
End Function

(public and private functions and subs similarly dictate whether they can be called from within or without their containing modules, but aren't directly related to the variables).

Some general reading on scope and lifetime is recommended. Chip Pearson (linked by jdraw) has one of the best VBA reference sites in existence, but sometimes can be a bit much for a beginner. In any case, googling "vba scope and lifetime" should land you plenty where you can find something at your level.

Cheers,
 

chrisjames25

Registered User.
Local time
Today, 23:03
Joined
Dec 1, 2014
Messages
401
Thank you both for your help. It was private level scope i was after. I kept not getting the string to populate as expected because it was dimmed at procedure level.

I will look into all the resources as think an understanding of this will be crucial going forwards.
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 18:03
Joined
Feb 28, 2001
Messages
27,001
Public StrTier1, StrTier11 As String

Two things are wrong with what you posted vs. what you later said you needed.

1. Syntax: This should be

Code:
Public StrTier1 As String, StrTier11  As String

As you had it written, StrTier1 was a Variant. You can STILL assign a string value to it and it will work just fine - but it is VERY SLIGHTLY less efficient if your intent is that it would ALWAYS be a string and NEVER anything else. I suspect that the difference would only be detectable by timing two loops, each with an iteration count of 1,000,000 or so and each using one of the two definitions.

2. Semantics: Make it

Code:
Private StrTier1 As String, StrTier11  As String

(Or instead of Private you could use Dim, since Private is the default, I think.)

And as you have already acknowledged, this declaration must be in the declaration area of the module to be visible to the rest of the module.
 

Uncle Gizmo

Nifty Access Guy
Staff member
Local time
Today, 23:03
Joined
Jul 9, 2003
Messages
16,245
Code:
Private StrTier1 As String, StrTier11  As String

(Or instead of Private you could use Dim, since Private is the default, I think.)

So you can write:-
Code:
Private StrTier1 As String

instead of:-
Code:
Dim StrTier1 As String


I didn't know that! I will give that a try when I writing my next piece of code...

In one way it's clearer and in another it's a bit confusing? Not sure about it really...
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 18:03
Joined
Feb 28, 2001
Messages
27,001
"Dim" is shorter, but for a class module it is all you need in the declaration area. In ANY area, actually, since "Public" in a class module is close to totally meaningless. Just for snorts and giggles look up the "Friend" declaration, which is a strange little category that isn't quite public but isn't quite private either.

Actually, the only time I ever used "Private" was when I built event code and the wizard declared the entry point that way.
 

Mark_

Longboard on the internet
Local time
Today, 16:03
Joined
Sep 12, 2017
Messages
2,111
As your original code is
Code:
Public StrTier1, StrTier11  As String
StrTier1 = "Category"
StrTier11 = "category"

are you trying to create constants? If so you would use CONST.

Public Const StrTier1 as String = "Category"
Public Const StrTier11 as String = "category"

In this case I'd use C_Tier1 and C_Tier11 so you know your dealing with a Constant that you added.
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 18:03
Joined
Feb 28, 2001
Messages
27,001
Good point, Mark. The only warning is if you ever pass one of those constants to a sub by reference, it gets confusing. I don't recall if you can actually do that, but if you do, it doesn't have the effect originally intended for the subroutine.
 

jleach

Registered User.
Local time
Today, 19:03
Joined
Jan 4, 2012
Messages
308
"Public" in a class module is close to totally meaningless.

Curious why you say that. Public and private methods and properties have as much use in class modules as they do anywhere else:

Code:
'Book class
Option Explicit

Private mPageCount As Integer
Private mCurrentPage As Integer

'readonly with internal validation
Public Property Get CurrentPage() As Integer
  CurrentPage = mCurrentPage
End Property
Private Property Set CurrentPage(i As Integer)
  If i < 1 OR > Me.PageCount Then Err.Raise 9 'out of range
  mCurrentPage = i
End Property

'readonly
Public Property Get PageCount() As Integer
  PageCount = mPageCount
End Property
Private Property Set PageCount(i as Integer)
  mPageCount = CalculatePageCount()
End Property

Public Sub GotoPage(PageNumber As Integer) 
  Me.CurrentPage = PageNumber
  ... other stuff
End Sub

A little rough around the edges but serves well enough for an example. I'm not sure I've ever written a module where I didn't want most of the implementation hidden in private procedures and have only the interface exposed through public ones.

Cheers,
 

Users who are viewing this thread

Top Bottom