The Macro Tech-Tips column is aimed at EMME/2 users which are already familiar with EMME/2 macro writing, but want to further improve their general macro writing skills.
In this issue, we first look at some methods to improve the general robustness and efficiency of macros. In the second part, we take a closer look at the new g-registers and show how these can be used to efficiently perform some quite elaborate tasks.
Suppressing Pauses during Macro Execution
Whenever a message is displayed on the screen and might immediately be followed by a clear screen command, EMME/2 pauses for a second or two in order to give the user enough time to look at the message before the screen is erased. This happens in particular each time a report has been sent to the print file (message ``x pages sent to print file''). While this pause is very useful when running EMME/2 interactively, it is in general not necessary when running a macro. Thus, macros that generate many small reports can often be sped up significantly by suppressing these pauses. This is done by activating bit 5 of the o-register, i.e. by adding the line
~o|32 at the beginning of
Avoiding format errors by limiting text length
EMME/2 is quite strict regarding the maximum size of text and alphanumeric items, and will usually generate a format error when an attempt is made to enter a string which is too long. Macros often construct strings (such as descriptions of matrices, scalars, zone group ensembles or extra attributes) according to the current context or from user supplied parameters. In order to avoid such macros becoming ``time-bombs'', it is necessary to take special precautions to ensure that the maximum string length is not exceeded. Since text register substitution allows access to substrings, this can be done by first storing the entire title or description in a text register and then passing only the properly limited substring to the program, e.g. as is done in the following result matrix specification dialog:
mf66 / active demand yes / change matrix header actdem / matrix name ~t1=Active Demand (sel-lk %1% %2% %3%) '%t1.40%' / matrix description (limit to max. 40 chars) ~?q=1 y / initialize data 0 / to zero
Testing for batch input errors
Errors which are detected when reading batch input files are usually warnings. As macro processing only stops automatically on fatal errors, but not on warnings, batch input errors occurring within a macro will often slip through unnoticed at the time they happen and are -if at all- only detected much later. To avoid the danger associated with such errors, any macro which performs batch input operations should be able to detect batch input errors, so that, if they happen, appropriate measures can be taken right away. Tracking this type of warning errors is best done by checking the global parameter NLERR (documented on page C-6 of the EMME/2 User Manual) which can be accessed by setting the value of the p-register to the corresponding index 32 and reading its contents. As this parameter is composed of the total number of errors of both types as well as the number of the last error detected, its value will only change during a batch input operation if errors were detected. The following small macro sequence shows the principle of how such a test can be implemented:
... ~p=32 ~x=%p% ... (perform batch input operations here) ~x-%p% ~?!x=0 ~/Batch input error detected! ...An example of a more elaborate implementation of checking the NLERR parameter can be found in the macro
errchk.mac, which is available on our web site.
Using the g-registers for computing histograms and distributions
Since the introduction of Release 8, the size of the
put()/get() stack of
EMME/2's expression parser has been increased to 250 and the stack values
can be accessed directly from macros via the new floating point
registers g1 - g250, both for reading and writing.
This opens up many new possibilities for direct interactions of
macros with function evaluations, as well as network and matrix
calculations. One such possibility is to efficiently compute
network histograms, i.e. sum up the value of some network expression
(e.g. vehicle-hours) by some arbitrary classification (e.g. district).
While in previous releases such a computation had to be done rather
inefficiently on a class-by-class basis,
it can now be done for up to 250 classes
simultaneously with a single expression of the
where class is an arbitrary sub-expression defining the classes (giving values in the range 1 to 250) and expr defines the quantity to be accumulated. Once the computation is performed, the results are contained in the registers g1 - g250 from where they can be accessed directly by the macro. The following macro sequence computes and displays the vehicle-hours per district (assumed in
~+;2.41;1;n;put(get(puti(@distr))+volau*timau/60.);;all;5 ~+;~x+1;~?!gx=0;~/District %%%x_3%%%:%%%gx.2_10%%% vhrs;~?x<250;~$The macro
nethist.mac(available on our web site) uses the above technique to compute, display and plot arbitrary network histograms.