Variables

A variable (also known as a local variable) is a placeholder for varying or changeable data. Variables play an important role in because they enable developers to write flexible tasks. Rather than entering data directly into a task step, a developer can use variables to represent the data. Then, when the task runs, the variables are replaced with real data. This makes it possible for a task to perform actions on values that may or may not be known until runtime. It also allows a single task the ability to hold different sets of data.

Variables are created and/or set in Task Builder during task creation. They are commonly used when a task involves collecting data from a source and then performing some action on it. You use the variable to contain the collected data, and then set up the actions to be performed on the data by referencing the variable. For example you could create a variable in the beginning of a task that will be populated with the user's input in a form or message box. In a subsequent step you could perform calculations on the data the user entered by referencing the variable.

Creating Variables

The Create variable activity generates a local variable which can be used to store dynamic values for utilization in any step of the task or any sub-tasks started with the Start Task action. The developer can enter a value to initially populate the variable during creation or the value field can be left blank. Instead, variables can be set with a value using the Set Variable action, which adds or changes the contents of an already existing variable. Certain available actions that support populating variables can also set or modify a variable's contents, such as the Input Box action. This action displays an input box allowing the user to enter a value which is saved to the variable specified.

Once a variable is created, it becomes available for use in subsequent steps of the task. It will appear on drop-down lists in places where a variable can be entered, and it can be used in expressions by simply placing the name of the variable between percent signs (%). For example, entering  %UserInput% tells to populate the expression with the current value of the variable named UserInput.

It is important to note that in order for a variable to be used in a task step, it must initially be created within an earlier step.

Variable Naming Conventions

Variable names must contain only alphanumeric characters, must start with a letter and cannot contain spaces. Variable names are not case-sensitive. When choosing a variable name, it is good practice to select a name that is descriptive of what the variable holds. For example, if a variable holds the size of a shoe, then name it ShoeSize or TheSize. This makes the task more comprehensible. Also, be sure to avoid using BASIC keywords, functions, or instructions. Names such as DATE or TIME would create a conflict. One way to avoid this is to include distinguishing characters in the variable name such as VAR, THE or MY. For example, a date variable could be named MyDate, DateVar or theDate.

Variable names must be unique within a task, but can be repeated from one task to the next. For example, if you create a variable in one task named UserInput, you can create a variable of the same name in another task without any conflict occurring.

Variable naming restrictions

There are limitations to the names that can be given to variables. These limitations derive from the fact that when the expressions between % signs are evaluated as a script, even if they are a simple variable name. Therefore all BASIC Script keywords, functions names, and operators are forbidden as variables names (e.g. while, wait, like, instr, date, time, now, daysinyear, etc ).

Also all Windows environment variables such as PATH, DATE, TMP, PROMPT are also reserved and cannot be declared as new variables. They are, however, accessible and readable, whether or not they were declared “as parameters” in an AMVARIABLE statement.

This is quite a lot of common names which are in fact reserved. Nothing warns that they are not allowed, but the error will appear at execution time, with some strange error message that is all but obvious to understand. A wise precaution to avoid any mistake is to initiate all variable names by a specific (group of) character(s), say v_ (underscore) which then allows variables like v_wait, v_do, v_while, v_path without any ambiguity.

Scoping & Accessibility

Local variables created within a task function (e.g., by using Create Variable, Create Array, etc.) are scoped to that function. Local variables, therefore, are not visible and thus cannot be used outside the function in which they are created.  If a variable is created within a function with the same name as a task variable, the local variable “hides” the task variable and takes precedence.  

Scoping a created variable to the function in which it is created has the following advantages:

  • Variables are only created when required - Because functions are distinct units designed for a single purpose, variables created within them are typically only needed to serve that purpose before returning an end result. Scoping the variables to the function keeps these variables localized to where they are needed. Once their purpose is complete, they are discarded.

  • Keeps temporary variables where they are needed - Many functions make use of temporary variables, for example when indexing an array, looping, etc. Local variables provide a means to create indexing or temporary variables that are only available within that function without creating a global variable that can be trampled on by other functions.  An example of the danger of using a common index variable without local scoping is creating an index variable named i that, in a loop, calls another function which itself uses a variable i  as an index.  When the second function is finished, the first function will have the wrong value!  Local variables avoid this problem.

  • It does not preclude the use of task variables - A function can still set and retrieve the value of a task variable, or assign a task variable the value of a local variable.  This improves readability and keeps the number of variables a user needs to remember or debug to a minimum.

  • Makes tasks easier to debug - The use of local variables and task variables means there are less variables the user needs to keep in their head at any given time.  “The less you have to keep in mind, the smaller the chance that you’ll make an error because you forgot one of the many details you needed to remember.”   Additionally, it provides a means to separate variables in a debugger or other visual display (see Design Time Implementation)

  • Allows recursion - Recursion is impossible without local variables. Recursion relies on local variables to store the state of the function during each call.  If a variable is scoped outside the function, each call of that function will overwrite the data of the previous call, thus rendering the recursion useless.

A local variable’s or local array's accessibility is defined by the Variable is private option on the Create Variable or Create Array step. By default, this option is set to OFF and therefore the variable's default accessibility is public. This means that an external task can access a public local variable.   

Sub-tasks

Sub-tasks are task files run synchronously at the step level using the Start Task action. Sub-tasks are treated as individual modules that maintain their own scope and accessibility. Sub-tasks can access public variables, functions and extended functions of the parent task, but not vice versa. Functions and variables contained in the sub-task, however, whether private or public, are accessible to functions called within the sub-task while the sub-task is executing, exactly as if the sub-task were running independently.  An important point to note regarding this is how events (which are functions that are optionally implemented by a task and called implicitly by the task engine) are scoped; a sub-task’s events are fired during sub-task execution, not the parent’s. This follows the rules of variable and function scoping and accessibility.