If I set a variable inside of a subroutine, it is set to nothing upon the end of the sub.
Can I set a variable outside a sub and set its value, so that you can use it within subs?
I'm new to coding.
note that when using variables within subs, it is better/clearer to pass the argument into the sub
so
declarations dim myvar as string myvar = "test"
[call] testvar1
this works sub testvar1 msgbox(myvar) end sub
and this works [call] testvar2(myvar)
sub testvar2(arg as string)
'the variable myvar is now aliased as arg within the sub msgbox(arg) end sub
the latter usage is possibly better, as it makes the use of the variables easier to follow, and makes the code blocks more reuseable.
slight variantion sub testvar2(byref arg as string) sub testvar2(byval arg as string)
in the former of these two (byref - which is the default), if you change arg in the sub, the orginal value of arg changes. In the latter, arg is a temporary value, and changes are not retained after the sub ends. Personally, I think byval is better and safer, and a lot of languages have byval as the default. Note that some (complex) argument types are actually passed byref irrespective of whether you use byref or byval.
ByVal isn't necessarily safer than ByRef. It's down to the developer to know which one applies to the situation. A developer should know what the default is and should know the effects of both as you've just briefly explained.
Post #5 indicates that the poster wants a constant value to which pbaldy rightly replied that a Constant is the way to go and I'm of the same opinion. In addition, if the rates are going to vary then perhaps the poster wants to save these values in a table.
If I set a variable inside of a subroutine, it is set to nothing upon the end of the sub.
Can I set a variable outside a sub and set its value, so that you can use it within subs?
One thing not mentioned yet is the ability to dimension a static variable inside a subroutine or function. This will retain the value after the routine or function has ended. It is still only usable within that subroutine or function's scope.
I have never been able to declare a Public Variable that is available to another module. The instructions seem simple: use the word 'Public' and and put the declaration in the Declaration section, but I always get the 'Variable Not Defined' error
Questions:
Is the Declaration section the part at the top that says:
'Option Compare Database 'Use database order for string comparisons
Option Explicit' ?
Should the declaration precede the above or follow?
Can you declare a Public in a form module and have it be available to modules not associated with a specific form and vice versa? I group various functions that multiple forms use in a section that VBA Project Explorer calls 'Modules'
Is there some Access setting that I need to change?
First, you must declare public things in General Modules in order to have them visible in a true sense of the word "public." The declaration area is that part that sits between the phrases "Option Compare Database" and "Option Explicit." In a class module, you can say it is public, but it really isn't public.
I just use Dim Public Constant 12345 as Long (or some similar syntax).
Second, in a class module definition, your issue is that the class dissolves when the associated object (form, report) closes. A static definition in a class module might persist but its definition is part of (a property of) the class module; those properties and definitions are not visible unless the class object is open.
Third, you CAN do a declaration of a public constant - but you CANNOT (DARE NOT) reference it with ByRef - because (if I remember this correctly) it is in a protected section of memory that cannot be modified. It is not that you modify it, but that you attempt to access it by a method that COULD modify it.
OK, it has been a while and this might have changed since the last time I tried this, but I recall something like a memory access violation being associated with a ByRef on a declared global constant. On the other hand, I haven't tried this since Access version 2 (yes, before they started calling it Acc95, Acc97, etc. etc.)
The syntax for ByVal makes a copy of the referenced object and that is up to you to diddle as you wish. Therefore, ByVal of a declared constant is not a problem.
I have never had problems in modifying the contents of a public variable declared in a general module. The updated value persists across all forms and reports that correctly reference the object by its public name. Warning, though... if you want to keep your program clean, don't duplicate names between two different general modules. Otherwise you will have to remember to qualify the reference - as ModuleA.Myname vs. ModuleB.Myname - and you use "." syntax because in that context, variables are PROPERTIES of the module and the "." is property syntax.
module1 'declarations
dim var1 as string 'private to module1
const con1 = 12 'private to module1
public var2 as string ' public throughout your app
public const con2 = 25 'public throughout your app
module2
'declarations
dim var1 as string 'legal
const con1 = 12 'legal
public var2 as string 'error - already declared in module1
public const con2 = 25 'error - already declared in module1
form module2
'declarations
dim var1 as string 'legal
const con1 = 12 'legal
public var2 as string 'error - already declared in module1
public const con2 = 25 'error - already declared in module1
note: the same variable names can be dimmed inside the modules, but not made public, as you then have duplicate declarations. because of the possibility of the same name being used for multiple declarations, you need to be careful that when you refer to a variable, you are aware of the scope of the variable
hence this usage
Code:
function myfunc(variable1 as long)
...
...
end function
call myfunc(var1)
is always better, as the function myfunc is clearly using the variable "variable1", and there can be no side effects caused by addressing the "wrong" variable within myfunc. The aim is to make myfunc a "black-box", that doesn't need to know anything about your app - just the values that are passed in to it, thereby making it reusable in other applications.
so for instance I have a function that writes a log file
Code:
function writelog(logfile as string, loginfo as string, optional openlog as Boolean=false) as Boolean
...
...
'return true or false for success/failure of the log
end function
the function writes the string loginfo into the named logfile, and immediately opens it for viewing if the openlog argument is set to true. the app does not need to know how this is achieved, and the function does not need to use any variables with scope outside of itself.