Discussion:
Declaring variables - confused
(too old to reply)
Leo Bramwell-Speer
2012-08-13 07:27:50 UTC
Permalink
Hi

Up until now I have been using the Dim keyword to declare variables,
either in the general section or within a procedure to define it's scope;
or the Public keyword to make that variable available to other modules. I
also understand about Constants & Static variables.

What I am confused about is what the difference is between 'Dim' &
'Private' (eg PRIVATE N AS INTEGER), ie using Private instead of Dim
seems to do exactly the same job. Is there a subtle difference? Which one
should I use?

Thanks in advance.
--
Leo
http://leobs.net/
Ivar
2012-08-13 08:51:53 UTC
Permalink
Not my words, but:

Dim and Private work the same, though the common convention is to use
Private at the module level, and Dim at the Sub/Function level. Public and
Global are nearly identical in their function, however Global can only be
used in standard modules, whereas Public can be used in all contexts
(modules, classes, controls, forms etc.) Global comes from older versions of
VB and was likely kept for backwards compatibility, but has been wholly
superseded by Public.
Leo Bramwell-Speer
2012-08-13 09:32:35 UTC
Permalink
Post by Ivar
Dim and Private work the same, though the common convention is to use
Private at the module level, and Dim at the Sub/Function level. Public
and Global are nearly identical in their function, however Global can
only be used in standard modules, whereas Public can be used in all
contexts (modules, classes, controls, forms etc.) Global comes from
older versions of VB and was likely kept for backwards compatibility,
but has been wholly superseded by Public.
I see, but now I have a new problem :( A project contains 2 forms, Form1 &
Form2. Form1 declares & assigns a public string & contains a command button
to show Form2 thusly (VB6 code):


Option Explicit
Public a As String

Private Sub Form_Load()
a = "Hello World!"
End Sub

Private Sub Command1_Click()
Load Form2
Form2.Show
End Sub


So far so good, but if I put this code in Form2...


Option Explicit

Private Sub Form_Activate()
Print a
End Sub


It errors as variable not defined :() I don't understand that at all.
--
Leo
http://leobs.net/
Henning
2012-08-13 09:44:55 UTC
Permalink
Post by Leo Bramwell-Speer
Post by Ivar
Dim and Private work the same, though the common convention is to use
Private at the module level, and Dim at the Sub/Function level. Public
and Global are nearly identical in their function, however Global can
only be used in standard modules, whereas Public can be used in all
contexts (modules, classes, controls, forms etc.) Global comes from
older versions of VB and was likely kept for backwards compatibility,
but has been wholly superseded by Public.
I see, but now I have a new problem :( A project contains 2 forms, Form1 &
Form2. Form1 declares & assigns a public string & contains a command button
Option Explicit
Public a As String
Private Sub Form_Load()
a = "Hello World!"
End Sub
Private Sub Command1_Click()
Load Form2
Form2.Show
End Sub
So far so good, but if I put this code in Form2...
Option Explicit
Private Sub Form_Activate()
Print a
End Sub
It errors as variable not defined :() I don't understand that at all.
--
Leo
http://leobs.net/
Public is "Global" only in a Module.

If Public a As String is declared in a Module, it would work as you use it.
In the above you need in Form2 to use Form1.a to access it.

/Henning
Leo Bramwell-Speer
2012-08-13 10:07:37 UTC
Permalink
Post by Henning
Post by Ivar
Dim and Private work the same, though the common convention is to
use Private at the module level, and Dim at the Sub/Function level.
Public and Global are nearly identical in their function, however
Global can only be used in standard modules, whereas Public can be
used in all contexts (modules, classes, controls, forms etc.) Global
comes from older versions of VB and was likely kept for backwards
compatibility, but has been wholly superseded by Public.
Public is "Global" only in a Module.
If Public a As String is declared in a Module, it would work as you
use it. In the above you need in Form2 to use Form1.a to access it.
/Henning
I see :) Thanks for explaining that - it's been troubling me all morning :)
--
Leo
http://leobs.net/
Leo Bramwell-Speer
2012-08-13 10:26:02 UTC
Permalink
Post by Ivar
Dim and Private work the same, though the common convention is to
use Private at the module level, and Dim at the Sub/Function level.
One last question, when you say module level, do you mean both standard
modules & form modules, ie when declaring in the general section of a form
module, you use Private?
--
Leo
http://leobs.net/
--
Leo
http://leobs.net/
Eduardo
2012-08-13 17:18:07 UTC
Permalink
Post by Leo Bramwell-Speer
Post by Ivar
Dim and Private work the same, though the common convention is to
use Private at the module level, and Dim at the Sub/Function level.
One last question, when you say module level, do you mean both standard
modules & form modules, ie when declaring in the general section of a form
module, you use Private?
Hello, look:

At the general section of the form, class or usercontrol (property pages,
etc):

Use Private for the variables that you need in that object module.
Use Public only for some special cases that you need the variable to be
accessed from outside of the object module. You need to access the variable
as ObjectName.VariableName (example Form1.MyVariable)

In a Standard module:

Use Private if the variables are to be used only inside the module.
Use Public if you need them to be visible globally in the whole project. In
this case you don't need to reference the module to access the variable,
just the variable name directly.

Variables inside a procedure:

Use Dim for declaring internal variables used only in that procedure.
Use Static for variables that are used only in the procedure, but still you
need them to preserve their values for the next time the procedure is
invoked (they are as the ones declared with Private in the general section,
but visible only inside that procedure).

Use some naming convention, so when you read the code, you know the scope of
the variable without having to go and see where it's declared and how it's
declared.
For example I use mVariableName for the variables declared at a module level
(Private), gVariableName for globals, etc.

Some people also put the variable type in the name, like m_strMyText where
the str means it is a string variable. That is up to your taste how to name
the variables, but some information about the variable makes the code more
easily readable (for you and for others).
Leo Bramwell-Speer
2012-08-13 17:48:55 UTC
Permalink
Post by Eduardo
At the general section of the form, class or usercontrol (property
Use Private for the variables that you need in that object module.
Use Public only for some special cases that you need the variable to
be accessed from outside of the object module. You need to access the
variable as ObjectName.VariableName (example Form1.MyVariable)
Use Private if the variables are to be used only inside the module.
Use Public if you need them to be visible globally in the whole
project. In this case you don't need to reference the module to access
the variable, just the variable name directly.
Use Dim for declaring internal variables used only in that procedure.
Use Static for variables that are used only in the procedure, but
still you need them to preserve their values for the next time the
procedure is invoked (they are as the ones declared with Private in
the general section, but visible only inside that procedure).
Use some naming convention, so when you read the code, you know the
scope of the variable without having to go and see where it's declared
and how it's declared.
For example I use mVariableName for the variables declared at a module
level (Private), gVariableName for globals, etc.
Some people also put the variable type in the name, like m_strMyText
where the str means it is a string variable. That is up to your taste
how to name the variables, but some information about the variable
makes the code more easily readable (for you and for others).
A very illuminating reply, thank you.
--
Leo
http://leobs.net/
Coder X
2012-08-14 01:21:27 UTC
Permalink
I can think of absolutely no good reason to declare anything public at the
form level. If some bit of data needs to be passed to and from a form, set
up a property. Actual Public/Global is as evil as End and DoEvents. Again,
better to use a property.
Post by Eduardo
Post by Leo Bramwell-Speer
Post by Ivar
Dim and Private work the same, though the common convention is to
use Private at the module level, and Dim at the Sub/Function level.
One last question, when you say module level, do you mean both standard
modules & form modules, ie when declaring in the general section of a form
module, you use Private?
At the general section of the form, class or usercontrol (property pages,
Use Private for the variables that you need in that object module.
Use Public only for some special cases that you need the variable to be
accessed from outside of the object module. You need to access the
variable as ObjectName.VariableName (example Form1.MyVariable)
Use Private if the variables are to be used only inside the module.
Use Public if you need them to be visible globally in the whole project.
In this case you don't need to reference the module to access the
variable, just the variable name directly.
Use Dim for declaring internal variables used only in that procedure.
Use Static for variables that are used only in the procedure, but still
you need them to preserve their values for the next time the procedure is
invoked (they are as the ones declared with Private in the general
section, but visible only inside that procedure).
Use some naming convention, so when you read the code, you know the scope
of the variable without having to go and see where it's declared and how
it's declared.
For example I use mVariableName for the variables declared at a module
level (Private), gVariableName for globals, etc.
Some people also put the variable type in the name, like m_strMyText where
the str means it is a string variable. That is up to your taste how to
name the variables, but some information about the variable makes the code
more easily readable (for you and for others).
ralph
2012-08-14 03:38:01 UTC
Permalink
Post by Coder X
I can think of absolutely no good reason to declare anything public at the
form level. If some bit of data needs to be passed to and from a form, set
up a property. Actual Public/Global is as evil as End and DoEvents. Again,
better to use a property.
Not sure where you got that idea that "Public/Global is as evil as
...". Would be interesting if you expanded on that.

A variable declared as Public in a Form or Class (the two modules are
identical in this respect) means that variable becomes part of the
Public or default interface of the Form or Class, and actually a
Public variable is converted behind the scenes into a Property, with a
default Let and Get (and Set if appropriate).

ie, if you type this in a Class module

Public Junk As Long

VB does this ...

' hidden storage
Private _Hidden_Junk As Long
' default Let
Public Property Let Junk(Value As Long)
_Hidden_Junk = Value
End Property
' default Get
Public Property Get Junk() As Long
Junk = _Hidden_Junk
End Property

The advantage of creating your own Property instead of just using the
default, is that while debugging the debugger will stop inside your
Property. It "skips" over the default. Also you may want to add extra
validation, etc.

You can see this phenomena easily by simply inheriting (by Implements)
a Form or Class that contains Public variables. You will discover you
can not merely provide a Public variable to satisfy the
implementation, but must also implement both the Let and Get (and Set
if necessary) Properties.

-ralph
ralph
2012-08-14 04:06:24 UTC
Permalink
Post by ralph
You can see this phenomena easily by simply inheriting (by Implements)
a Form or Class that contains Public variables. You will discover you
can not merely provide a Public variable to satisfy the
implementation, but must also implement both the Let and Get (and Set
if necessary) Properties.
In the above I said "... can not merely provide a Public variable...".

This would be wrong, because naturally you can't use the keyword
"Public" for your new interface as that would make it part of the
module's public/default interface, and not part of the inherited
interface.

What I probably should have said was something more like ...

You will discover you can not merely provide a *single* variable, such
as "Private Interface_Junk As Long", but must implement the
Get/Let/[Set] "default" Properties and a store.

Also while I hinted, it is probably useful to point out more strongly
that Coder X's suggestion to use a Property over a simple Public
declaration is generally a good idea, but not because "Public"
variables are evil, but just because they provide flexibility. (ie,
you get the code anyway - why not show it. <g>)

If the extra typing is a concern, note that VB6 contains a Class
Builder designer which allows one to generate Properties quickly.

MZTools is also very useful.
http://www.mztools.com/v3/mztools3.aspx

-ralph
Eduardo
2012-08-14 20:14:45 UTC
Permalink
Post by Coder X
I can think of absolutely no good reason to declare anything public at the
form level. If some bit of data needs to be passed to and from a form, set
up a property. Actual Public/Global is as evil as End and DoEvents.
Again, better to use a property.
In most of cases yes, but there are some cases that you don't need a
property, it only would take (a bit of) more processing time without a
benefit.
ralph
2012-08-14 20:32:21 UTC
Permalink
Post by Eduardo
Post by Coder X
I can think of absolutely no good reason to declare anything public at the
form level. If some bit of data needs to be passed to and from a form, set
up a property. Actual Public/Global is as evil as End and DoEvents.
Again, better to use a property.
In most of cases yes, but there are some cases that you don't need a
property, it only would take (a bit of) more processing time without a
benefit.
As a Public in a Form is converted to a Property, I can see how there
might be more clicks involved in pcode, but nothing measurable in
native compiled code.

A Property vs a Global in a .bas module would definitely add clicks,
but there the benefit is often substantial.

-ralph
Eduardo
2012-08-14 21:02:39 UTC
Permalink
Post by ralph
As a Public in a Form is converted to a Property, I can see how there
might be more clicks involved in pcode, but nothing measurable in
native compiled code.
I don't know how the compiler works so...

You mean that

Public VariableName as Long

is exactly the same (in terms of performance) that:

Private mVariableName as Long

Public Property Let VariableName (nValue as Long)
mVariableMane = nValue
End Property

Public Property Get VariableName() as Long
VariableName= mVariableName
End Property

??

Even if it's the same in terms of performance, it's not the same in terms
of lines to be written.
Post by ralph
A Property vs a Global in a .bas module would definitely add clicks,
but there the benefit is often substantial.
Sometimes there are not real benefits.

Many times I wrote with Public variables to make is fast, and a time later I
converted them to properties (for some reason).

A case where I don't see any benefit are the classes used like UDTs. In
those cases public variables are OK.
Eduardo
2012-08-14 21:06:12 UTC
Permalink
BTW, I think we had this discussion before. What was the conclusion?... I
can't remember exactly but I think something like "it's better practice for
future further development, but it still works (with public variables)".
ralph
2012-08-15 02:27:45 UTC
Permalink
Post by Eduardo
Post by ralph
As a Public in a Form is converted to a Property, I can see how there
might be more clicks involved in pcode, but nothing measurable in
native compiled code.
I don't know how the compiler works so...
You mean that
Public VariableName as Long
Private mVariableName as Long
Public Property Let VariableName (nValue as Long)
mVariableMane = nValue
End Property
Public Property Get VariableName() as Long
VariableName= mVariableName
End Property
??
Even if it's the same in terms of performance, it's not the same in terms
of lines to be written.
Yes. Both for performance and "lines" of code.

Because all *Public variables* are converted to a Property in a Form
or Class module. Thus the running code is identical whether declared
as a single variable or spelled out as a Property.

[I gave an out to such code running in pcode. But even that may not be
the whole truth. I based that on the fact if one examines the 'pcode'
(opcode or excode) in the VBIDE there is a difference between "typed
in" Properties and the equivalent "default" Properties. It looks like
a tad more "clicks" for the former. However, if you examine compiled
code - you will see little to no difference. Probably should not have
even gone there. I just figured if I left that out and said "no
difference" - someone would call me on it - so I played safe. <g>]
Post by Eduardo
Post by ralph
A Property vs a Global in a .bas module would definitely add clicks,
but there the benefit is often substantial.
Sometimes there are not real benefits.
Many times I wrote with Public variables to make is fast, and a time later I
converted them to properties (for some reason).
A case where I don't see any benefit are the classes used like UDTs. In
those cases public variables are OK.
Sure they are "OK". More than OK - perfectly good code.

The point of my initial post was to point out that neither is or can
be "evil" - simply because they are both the same. Not as to which
style is "better".

"Public VariableName as Long" is simply short-hand for generating a
Property.

Perhaps a better way to think of Public vs Property is to decide if
you want to go with the hidden default or if you want a "code
presence".

There are many situations (including the example you gave) where a
single variable is fine, even to me. The code is simple. Easy to read.
Looks fine. And darn sure saves a ton of typing. <g>

I tend to go with spelling out Properties with a "code presence" for
the following reasons...
1) Typing time is of little consequence to me because I use a variety
of code generators. I mouse-click more than I type, and ponder more
than I click. <g>
2) I like to only code once. I'm there, why not spell it out and be
done with it. <g>
If later on I decide to add validation, make a change to read-only,
etc. The code is already there.
3) I like the fact that during debugging the code stops in the
Property, inside the class or form.
4) Since most of my code is in this style - I don't mind the clutter.
<g>

But note. This is all just my opinion. My comfort zone. My Bennies.

-ralph
Deanna Earley
2012-08-15 07:55:19 UTC
Permalink
Post by ralph
"Public VariableName as Long" is simply short-hand for generating a
Property.
It's also worth remembering that as it's effectively a property, it can
no longer be passed to a procedure ByRef.
The same applies to class level public variables/properties, but NOT to
module level Public variables which can be passed ByRef.

(This has caught me out before when moving some (150! :) public
variables from a module to a class instance!)
--
Deanna Earley (***@icode.co.uk)
i-Catcher Development Team
http://www.icode.co.uk/icatcher/

iCode Systems

(Replies direct to my email address will be ignored. Please reply to the
group.)
ralph
2012-08-16 16:46:51 UTC
Permalink
On Wed, 15 Aug 2012 08:55:19 +0100, Deanna Earley
Post by Deanna Earley
Post by ralph
"Public VariableName as Long" is simply short-hand for generating a
Property.
It's also worth remembering that as it's effectively a property, it can
no longer be passed to a procedure ByRef.
The same applies to class level public variables/properties, but NOT to
module level Public variables which can be passed ByRef.
(This has caught me out before when moving some (150! :) public
variables from a module to a class instance!)
Thanks for posting that.

While I was writing a example to demonstrate that Form/Class Public
variables were Properties and not a 'single' variable, I knew there
was another "proof", but couldn't bring it forward in my cortex. <g>

-ralph
ralph
2012-08-16 17:45:00 UTC
Permalink
On Wed, 15 Aug 2012 08:55:19 +0100, Deanna Earley
Post by Deanna Earley
Post by ralph
"Public VariableName as Long" is simply short-hand for generating a
Property.
It's also worth remembering that as it's effectively a property, it can
no longer be passed to a procedure ByRef.
The same applies to class level public variables/properties, but NOT to
module level Public variables which can be passed ByRef.
(This has caught me out before when moving some (150! :) public
variables from a module to a class instance!)
I might add that I consider that a good feature.

[Note: Once again this is purely MHO. <g>]

Basically if a procedure is going to modify the state of Form/Class
then it is better to pass the whole object. Especially with objects of
the type Eduardo was describing.

It also adds to the value of implementing "Global" variables (.bas
modules) as Properties instead of a 'single' variable on occasion.
Global's can be troublesome enough to ferret out without accidentally
passing one as a ByRef parameter. <g>

-ralph

Loading...