Writing Efficient and Portable Macros |
Using Portable SAS Language Functions with %SYSFUNC |
If your code runs in two different environments, you have essentially doubled the worth of your development effort. But portable applications require some planning ahead. For more details about any host-specific feature of SAS, see the SAS documentation for your host environment.
You can use the %SYSFUNC macro function to access SAS language functions to perform most host-specific operations, such as opening or deleting a file. For more information, see %SYSFUNC and %QSYSFUNC Functions.
Using %SYSFUNC to access portable SAS language functions can save you a lot of macro coding (and is therefore not only portable but also more efficient). The following table lists some common host-specific tasks and the functions that perform those tasks.
Task | SAS Language Function or Functions |
---|---|
assign and verify existence of fileref and physical file | FILENAME, FILEREF, PATHNAME |
open a file | FOPEN, MOPEN |
verify existence of a file | FEXIST, FILEEXIST |
get information about a file | FINFO, FOPTNAME, FOPTNUM |
write data to a file | FAPPEND, FWRITE |
read from a file | FPOINT, FREAD, FREWIND, FRLEN |
close a file | FCLOSE |
delete a file | FDELETE |
open a directory | DOPEN |
return information about a directory | DINFO, DNUM, DOPTNAME, DOPTNUM, DREAD |
close a directory | DCLOSE |
read a host-specific option | GETOPTION |
interact with the File Data Buffer (FDB) | FCOL, FGET, FNOTE, FPOS, FPUT, FSEP |
assign and verify librefs | LIBNAME, LIBREF, PATHNAME |
get information about executed host environment commands | SYSRC |
Note: Of course, you can also use other functions, such as ABS, MAX, and TRANWRD, with %SYSFUNC. A few SAS language functions are not available with %SYSFUNC. See %SYSFUNC and %QSYSFUNC Functions for more details.
Example Using %SYSFUNC |
The following program deletes the file identified by the fileref MYFILE:
%macro testfile(filrf); %let rc=%sysfunc(filename(filrf,physical-filename)); %if &rc = 0 and %sysfunc(fexist(&filrf)) %then %let rc=%sysfunc(fdelete(&filrf)); %let rc=%sysfunc(filename(filrf)); %mend testfile; %testfile(myfile)
Using Automatic Variables with Host-Specific Values |
The automatic macro variables are available under all host environments, but the values are determined by each host. The following table lists the macro variables by task. The "Type" column tells you if the variable can be changed (Read/Write) or can be inspected (Read Only).
Task | Automatic Macro Variable | Type |
---|---|---|
list the name of the current graphics device on DEVICE=. | SYSDEVIC | read and write |
list of the mode of execution (values are FORE or BACK). Some host environments allow only one mode, FORE. | SYSENV | read-only |
list the name of the currently executing batch job, user ID, or process. For example, on UNIX, SYSJOBID is the PID. | SYSJOBID | read-only |
list the last return code generated by your host environment, based
on commands executed using the X statement in open code, the X command in
the SAS windowing environment, or the %SYSEXEC (or %TSO or %CMS) macro statements.
The default value is 0. |
SYSRC | read and write |
list the abbreviation of the host environment you are using. | SYSSCP | read-only |
list a more detailed abbreviation of the host environment you are using. | SYSSCPL | read-only |
retrieve a character string that was passed to SAS by the SYSPARM= system option. | SYSPARM | read and write |
The macro DELFILE uses the value of SYSSCP to determine the platform that is running SAS and deletes a TMP file. FILEREF is a macro parameter that contains a filename. Because the filename is host-specific, making it a macro parameter enables the macro to use whatever filename syntax is necessary for the host environment.
%macro delfile(fileref); /* Unix */ %if &sysscp=HP 800 or &sysscp=HP 300 %then %do; X "rm &fileref..TMP"; %end; /* DOS-LIKE platforms */ %else %if &sysscp=OS2 or &sysscp=WIN %then %do; X "DEL &fileref..TMP"; %end; /* CMS */ %else %if &sysscp=CMS %then %do; X "ERASE &fileref TMP A"; %end; %mend delfile;
Here is a call to the macro DELFILE in a PC environment that deletes a file named C:\SAS\SASUSER\DOC1.TMP:
%delfile(c:\sas\sasuser\doc1)
In this program, note the use of the portable %SYSEXEC statement to carry out the host-specific operating system commands.
Now, suppose you know your macro application is going to run on some version of Microsoft Windows. The SYSSCPL automatic macro variable provides information about the name of the host environment, similar to the SYSSCP automatic macro variable. However, SYSSCPL provides more information and enables you to further tailor your macro code.
Example Using SYSPARM |
Suppose the SYSPARM= system option is set to the name of a city. That means the SYSPARM automatic variable is set to the name of that city. You can use that value to subset a data set and generate code specific to that value. Simply by making a small change to the command that invokes SAS (or to the configuration SAS file), your SAS job will perform different tasks.
/* Create a data set, based on the value of the */ /* SYSPARM automatic variable. */ /* An example data set name could be MYLIB.BOSTON. */ data mylib.&sysparm; set mylib.alltowns; /* Use the SYSPARM SAS language function to */ /* compare the value (city name) */ /* of SYSPARM to a data set variable. */ if town=sysparm(); run;
When this program executes, you end up with a data set that contains data for only the town you are interested in, and you can change what data set is generated before you start your SAS job.
Now suppose you want to further use the value of SYSPARM to control what procedures your job uses. The following macro does just that:
%macro select; %if %upcase(&sysparm) eq BOSTON %then %do; proc report ... more SAS code; title "Report on &sysparm"; run; %end; %if %upcase(&sysparm) eq CHICAGO %then %do; proc chart ... more SAS code; title "Growth Values for &sysparm"; run; %end; . . /* more macro code */ . %mend select;
SYSPARM Details |
The value of the SYSPARM automatic macro variable is the same as the value of the SYSPARM= system option, which is equivalent to the return value of the SAS language function SYSPARM. The default value is null. Because you can use the SYSPARM= system option at SAS invocation, you can set the value of the SYSPARM automatic macro variable before your SAS session begins.
SYSRC Details |
The value of the SYSRC automatic macro variable contains the last return code generated by your host environment. The code returned is based on commands you execute using the X statement in open code, the X command a windowing environment, or the %SYSEXEC macro statement (as well as the nonportable %TSO and %CMS macro statements). Use the SYSRC automatic macro variable to test the success or failure of a host environment command.
Note: While it does not generate an error message in the SAS log, the SYSRC automatic macro variable is not useful under all host environments. For example, under some host environments, the value of this variable is always 99, regardless of the success or failure of the host environment command. Check the SAS companion for your host environment to determine whether the SYSRC automatic macro variable is useful for your host environment.
Macro Language Elements with System Dependencies |
Several macro language elements are host-specific, including the following:
Examples of such expressions include %DO, %DO %UNTIL, %DO %WHILE, %IF-%THEN, and %EVAL.
For example, consider the following program:
%macro testsort(var); %if &var < a %then %put *** &var is less than a ***; %else %put *** &var is greater than a ***; %mend testsort; %testsort(1) /* Invoke the macro with the number 1 as the parameter. */
On EBCDIC systems, such as z/OS, and VSE, this program causes the following to be written to the SAS log:
*** 1 is greater than a ***
But on ASCII systems (such as UNIX or Windows), the following is written to the SAS log:
*** 1 is less than a ***
The MSYMTABMAX system option specifies the maximum amount of memory available to the macro variable symbol tables. If this value is exceeded, the symbol tables are stored in a WORK file on disk.
The MVARSIZE system option specifies the maximum number of bytes for any macro variable stored in memory. If this value is exceeded, the macro variable is stored in a WORK file on disk.
The default delimiters that the %SCAN and %QSCAN functions use to search for words in a string are different on ASCII and EBCDIC systems. The default delimiters are
ASCII systems |
blank . < ( + & ! $ * ) ; ^ - / , % | |
EBCDIC systems |
blank . < ( + | & ! $ * ) ; ¬ - / , % ¦ ¢ |
The %SYSEXEC, %TSO, and %CMS macro statements enable you to issue a host environment command.
On some host environments, the %SYSGET function returns the value of host environment variables and symbols.
The SYSPARM= system option can supply a value for the SYSPARM automatic macro variable at SAS invocation. It is useful in customizing a production job. For example, to create a title based on a city as part of noninteractive execution, the production program might contain the SYSPARM= system option in the SAS configuration file or the command that invokes SAS. See SYSPARM Details for an example using the SYSPARM= system option in conjunction with the SYSPARM automatic macro variable.
The SASMSTORE= system option specifies the location of stored compiled macros.
The SASAUTOS= system option specifies the location of autocall macros.
Host-Specific Macro Variables |
Some host environments create unique macro variables. These macro variables are not automatic macro variables. The following tables list some commonly used host-specific macro variables. Additional host-specific macro variables might be available in future releases. See your SAS companion for more details.
Variable Name | Description |
---|---|
SYS99ERR | SVC99 error reason code |
SYS99INF | SVC99 info reason code |
SYS99MSG | YSC99 text message corresponding to the SVC error or info reason code |
SYS99R15 | SVC99 return code |
SYSJCTID | value of the JCTUSER field in the JCT control block |
SYSJMRID | value of the JMRUSEID field in the JCT control block |
SYSUID | the TSO user ID associated with the SAS session |
Naming Macros and External Files for Use with the Autocall Facility |
When naming macros that will be stored in an autocall library, there are restrictions depending on your host environment. Here is a list of some of the restrictions:
Every host environment has file naming conventions. If the host environment uses file extensions, use .sas as the extension of your macro files.
Although SAS names can contain underscores, some host environments do not use them in the names of external files. Some host environments that do not use underscores do use the pound sign (#) and might automatically replace the # with _ when the macro is used.
Some host environments have reserved words, such as CON and NULL. Do not use reserved words when naming autocall macros or external files.
Some hosts have host-specific autocall macros. Do not define a macro with the same name as these autocall macros.
Macro catalogs are not portable. Remember to always save your macro source code in a safe place.
On UNIX systems the filename that contains the autocall macro must be all lowercase letters.
Copyright © 2009 by SAS Institute Inc., Cary, NC, USA. All rights reserved.