This section is not intended as a general introduction to EMME/2 macros. Rather, it was written with the intention of being ``a quick refresher'' for users that have already worked with the macro language, but do not have the same degree of familiarity with all features of the language.
In order to get an idea what the concept of ``macros'' in the context of EMME/2 is all about, let us first look at the general framework how the operation of the EMME/2 package is controlled by the user.
The basic method of telling EMME/2 what to do is based on the notion of dialog. The dialog consists of a sequence of interactions in which the system asks questions, which in turn are answered by the user. The structure of this dialog is quite simple, as there are only three well defined types of questions that make up the dialog:
When EMME/2 is used interactively, all answers to the questions asked in the dialog are provided by the user, who is typing them at the keyboard as he goes along. The macro language provided in EMME/2 is simply a mechanism which generates these answers automatically, according to a macro script. In other words, whatever a user can do by operating the EMME/2 dialog interactively can also be implemented in a macro.
Therefore, in its simplest form, a macro consists of just a straight sequence of pre-defined answers that are passed back, one after the other, to the EMME/2 dialog. However, in most real-life applications, this would not be good enough, as the answers that need to be generated by the macro are seldomly exactly the same from one run to the other. To address this need, the macro language incorporates many features that allow the implementation of ``intelligent'' macros, such as:
get()/put()stack of the expression evaluator (read/write).
In the remaining part of this section, a brief overall summary of the EMME/2 macro language is given, based on the implementation in EMME/2 Release 8.
Various types of macro registers are available. Some of them are read-only registers which contain system defined parameters, others are writable by the macro, so that they take the role of programming variables, which can be used for computations, counters, etc. All numeric registers are restricted to integer values. Text registers have a maximum length of 128, but since the maximum macro line length is also limited to 128, it is normally not possible to attain this maximum. The following table gives an overview of all available registers.
|b||integer||read-only||Batch mode indicator (1:interactive, 2:batch). In batch mode all reports are written to the report file, all plots are written to the plot file, without corresponding select questions and regardless of the settings of switches 0 and 1. Also, in batch mode, no change of range is possible after a plot is generated with modules 2.43, 3.16 or 4.13, the module returns to the primary select right after the plot is terminated.|
|d||integer||read-only||Date register. Contains a six digit integer value of the form YYMMDD, where YY indicates the year (0-99), MM the month (1-12) and DD the day of the month (1-31).|
|e||integer||read-only||Number of last error. This register contains the number of the last error (warning or fatal) which has occurred, as described in Appendix A of the User's Manual. It can be used to take the corrective action after an abortive error condition has been detected, or also to determine, if errors occurred while reading a file using batch input.|
|f||integer||read-only||Scenario status flags for current scenario. This register contains a bit pattern defined as follows: bit 0: protected against forced module execution bit 1: protected against network modifications bit 2: protected against scenario deletion bit 5: ready for an auto assignment bit 6: ready for a transit assignment bit 10: contains valid auto assignment bit 11: contains valid transit assignment|
|i||integer||read-only||Bit pattern containing the current state of switches 0-31. See User's Manual for definition of the individual switches.|
|m||integer||read-only||Current module number. This register contains the number of the currently active module as a 3-digit integer value.|
|q||integer||read-only||Type of current dialog question. This register can be used to
determine the type of question the macro is currently expected to answer.
A value of 1 indicates a Yes/No question, a value N>1 indicates
a Select question with N alternatives, and a value of 0
is used for Enter questions. A value of -1 indicates an extra input line
generated when bit 6 of the control register |
|s||integer||read-only||Number of the current scenario.|
|v||integer||read-only||Version of current module. This register contains an integer value which indicates the major release level (hundreds and up) and the minor update level (last two digits) of the current module.|
|x,y,z||integer||read/write||General purpose integer registers. These three registers can be used by the macro to hold or compute any type of numeric information.|
|p||integer|| The p register provides a convenient
mechanism to access system, global and scenario parameters. When a value
is written into the p registers, it is interpreted as the address
of one of these parameters. When, on the other hand, the value of the
p register is read (e.g. in the substitution |
|o||integer||read/write||The o register contains a bit pattern, which can be used to control the various aspects of the dialog output. See section 6 for further discussion.|
|r1-r250||real||read/write||General purpose single precision floating point
registers. These registers can be used to hold and manipulate any kind
of numeric information. Instead of specifying the register number explicitly,
it is also possible to use one of the registers x, y or z
as index register, e.g. if |
|g1-g250||real||read/write||These single precision floating point registers are
used to directly access the elements of the |
|t0-t9||text||read/write|| Ten text registers of up to 128 characters are
available. The register t0 is special in that it always
corresponds to the current macro calling parameters %1% %2% %3% ... .
Thus, changing the contents of t0 will always affect the macro
parameters, and, vice versa, modifying the macro parameters (e.g. with
As explained above, the basic task of a macro is to provide ``automatic'' answers to the EMME/2 dialog. Since often these answers depend on the context, an important component of the macro language is a general substitution mechanism which can be used to implement such dependencies. Those parts of the answers that are not fixed, but have to be replaced by context dependent information at the time the macro is executed, are coded into the macro text as substitution keys. These keys are always surrounded by % signs (e.g. %1% or %ms77.6%), in order to make them easily recognizable and to prevent ambiguities with the fixed parts of the macro text. At execution time, all valid substitution keys are replaced by their corresponding current value.
The following table contains a list of all possible substitutions:
|%0%||Current number of macro parameters. This number is always between 0 and 9. Since at most 9 parameters are available for direct substitution, the number does not exceed 9, even if the number of actual parameters is larger than 9. Often %0% is used to determine if a macro has been called with the correct number of parameters.|
|%1% ... %9%||Macro parameters 1 to 9. If a parameter is not defined it is substituted by an empty string. Note that the text register t0 always corresponds to the current macro parameters.|
|%reg%||Value of register reg.|
|%reg||Value of integer or floating pointregister reg using a predefined field width of W characters. If the value does not completely use the specified field width, it is adjusted to the right.|
|%freg.D%||Value of integer or floating point register freg using D digits after the decimal point.|
|%freg.D||Value of floating point register freg using D digits after the decimal point and a predefined field width of W characters.|
|%u%||User initials, as specified at session start.|
|%tN.L.%||The first L characters of text register tN.|
|%tN.-L.%||The contents of the text register tN without the first L characters.|
%msN.D||The substitution key is replaced by the value of a scalar. N can be a number between 1 and 99, or alternatively, one of the letters x, y or z. In the latter case, the scalar is addressed indirectly by using the scalar number which corresponds to the current value of the corresponding register. By default, automatic formatting is used, which eliminates redundant trailing zero decimals. If needed, the scalar identifier can optionally be followed by a decimal point and a digit between 0 and 9, and/or an underscore character followed by a field width. In this case, the format conversion is forced to use the corresponding number of digits after the decimal point and/or the specified field width. Note that when D=9, the default automatic format conversion is used.|
|%msN.n%||Same as above, but the name of the scalar is substituted instead of its value. Any trailing blanks are removed from the 6 character name.|
|%msN.d%||Same as above, but the description of the scalar is substituted instead of the scalar value or name. Trailing blanks are removed from the 40 character description.|
|%%%||This sequence is substituted by a single %. This is often useful for preventing the substitution of a valid substitution key.|
in the macro file that do not start with the tilde character (
assumed to be dialog answers. After the applicable substitutions
have been made (if any), they are passed back to the calling module.
Lines in the macro file which start with a tilde character (
or alternately with a blank followed by a tilde character,
are called macro commands. These commands are used to control
the macro's operation without necessarily generating a dialog answer.
The following list summarizes the available commands and their syntax.
| Comment line. When a comment is encountered during
the processing of the macro, the comment line is copied to the screen and
the processing continues without further actions. If the bit 1 of the
o-register is set to OFF, the comment command is copied as a whole to
the screen, if set to ON, the leading |
| Comment with no line-feed. This variant of the
comment command is similar to |
| Read line from keyboard. This command will
interactively read one line from the keyboard. An optional text string
can be given after the command, which will be displayed as a prompt on
the same line on which the answer is to be typed in by the user. If no
prompt string is specified, the string ``|
| Define address label.
This command is used to define a branch target address in the macro.
The execution of a branch command with the same label string
| Branch to specified address label. In the simple branch statement
| Discard current first parameter %1% and shift remaining macro parameters
by one position to the left. The second parameter will be moved into
position 1 (%1% %2%) , the third into position 2 (%2%
%3%), and so on. This command is useful when a macro does the same operation
on all specified parameters. In this case, the operation is implemented for
the first parameter using %1%, then the parameters are shifted using the
| This class of commands is used to initialize a writable text or integer
register reg to a given value value. reg can be any of
of the integer registers p, o, x, y or z,
the floating point registers |
| This class of commands is used to perform an integer arithmetic operation
on a writable numeric register reg, where
reg can be any of
of the integer registers p, o, x, y or z,
or the floating point registers |
| Conditional. This command is used to test the current contents of a
register reg against a given value value.
The following comparison operators are available:
| Test for error condition. This command is used to detect if an error
condition has (or has not) occurred since the last macro command.
The line following
| Call macro as a sub-procedure of the current macro. The specified macro
macro is executed with the given parameters. Upon termination of
the lower level macro, the current level macro continues its execution normally.
Each level of macro invocation sees its own private set of registers.
The values of these private registers are initialized to the current values
of the same registers in the calling macro, but they can be modified by
the called macro at will, without danger of disturbing the macros at higher
levels. Text register |
|Command escape to the operating system. The external command is passed to and executed by the underlying operating system. This command allows any kind of external programs and procedures to be integrated into a macro. Since the operating system depends on the installation, imprudent use of this command will result in macros that will only run in a particular operating environment.|
| Compound macro command. This command can be used to ``pack'' several
dialog answer lines and macro commands into a single physical line of the macro.
The character immediately following |
~>macrofile p1 p2 p3 ... (this mode of operation is also referred to as macro learn mode. The basic functions of the macro are then carried out interactively while EMME/2 is transcribing all dialog input into the designated macro file. Note that during this process it is already possible to define and use macro parameters, as well as any other substitution keys. This is done by specifying the values of the macro parameters which are to be used while the macro is being saved on the command line. Then, while interactively creating the macro, whenever a part of the input is not fixed, but needs to be substituted when the macro is executed later on, the user enters the substitution keys instead of their actual current values. The substitution mechanism will now do the necessary replacement even during the interactive macro definition. In this way, a macro is created which already contains the proper substitution keys. An empty save command (
~>- no file name!) is used to terminate the saving of a macro in learn mode.
While a macro is created using the ``save macro'' command, it is also
possible to enter directly some of the more simple macro commands, such as
~/...), register assignments and operations, label
definitions and read line (
~*). Other commands, such as conditionals,
branching and compound commands, are not accepted in the macro learn mode
and will have to be added later by explicit editing of the macro file.
%1%. Matrix name and description are given by the macro context.