Setting a variable before a subroutine

Is it necessary to redefine a variable within a subroutine? In a context such as this:

set AccrueMonth to February
MonthlyAccrue()

on MonthlyAccrue()
		tell application "Microsoft Excel"
		activate
		repeat with i from 1 to 24
			set PayrollSheet to ("Payroll (" & (i as text) & ")")
			tell sheet PayrollSheet
				if (get value of range "D42") is not "" then
					set SheetMonth to month of (get value of range "D42")
					if SheetMonth is equal to AccrueMonth then

I receive an error message that AccrueMonth is not defined. If I use the line “set AccrueMonth to February” after the call “on MonthlyAccrue” it works correctly. Is the variable not “passed” to the subroutine? Sorry if I’m not using the correct vocabulary.

Thanks,

Tom Carlson

Hi Tom,

a variable defined simply with the set or copy command is a local variable,
it is only visible in the current scope (each handler or script object has its own scope).

you can declare a variable as global, then it’s visible in all scopes


global AccrueMonth
set AccrueMonth to February
MonthlyAccrue()

on MonthlyAccrue()
.
		

or define a property, which is also visible from everywhere


property AccrueMonth : ""
set AccrueMonth to February
MonthlyAccrue()

on MonthlyAccrue()
.

or pass the parameter through the handler call


set AccrueMonth to February
MonthlyAccrue(AccrueMonth)

on MonthlyAccrue(M)
		tell application "Microsoft Excel"
		activate
		repeat with i from 1 to 24
			set PayrollSheet to ("Payroll (" & (i as text) & ")")
			tell sheet PayrollSheet
				if (get value of range "D42") is not "" then
					set SheetMonth to month of (get value of range "D42")
					if SheetMonth is equal to M then

Thanks, Stefan.

So as I understand it, the variables get passed to the subroutine in the same position as they were in the call handler, even if they have different names. And they will relate to the Call in the same order as they are between the ()? Do the variables then pass back up to the script when the subroutine finishes running? Or does that require declaring them as global? I am expanding my script to examine each month of the year, and would like to be able to not duplicate calculations. So, if I could pass the sheet number where I left off when I exited the repeat back up to the handler, I could pick up on the next sheet when I move to the next month. My sheets are chronological.

Thanks for all of your help. The script is coming along nicely. Most importantly, I’m having a lot of fun learning about scripting along the way.

Tom

Think of the variable in the subroutine as a new variable that is being given the value of the variable passed in. There is no relation. If you want the variable throughout the script to be one variable, you should set it as Global or a Property. Property is nice if you want to set an initial value right at the beginning of the script.

set AccrueMonth to February
MonthlyAccrue(AccrueMonth)

on MonthlyAccrue(M) --Think of this as set M to February (not M is linked in some way to AccrueMonth)

Having said that, it is possible to pass the resulting value of M back out and then re-set AccrueMonth to the new value of M coming out of the sub-routine. I don’t usually do this so I don’t know the correct syntax off the top of my head but I’m sure someone else does (and by “someone” I am assuming it will be Stefan:)).

Example:

set example to 2
--> 2

set example to multiplyByTwo(example)
--> 4

on multiplyByTwo(someNumber)
	return someNumber * 2
end multiplyByTwo