Writing 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.
Portable SAS Language Functions and Their Uses
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

Macro Variables by Task

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 and Write) or can be inspected (Read Only).
Automatic Macro Variables with Host-Specific Results
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 that you are using.
SYSSCP
Read-only
List a more detailed abbreviation of the host environment that you are using.
SYSSCPL
Read-only
Retrieve a character string that was passed to SAS by the SYSPARM= system option.
SYSPARM
Read and write

Examples Using SYSSCP and SYSSCPL

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 that 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 that 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:
any language element that relies on the sort sequence
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 ***
MSYMTABMAX=
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.
MVARSIZE=
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.
%SCAN and %QSCAN
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 . < ( + | & ! $ * ) ; ¬ − / , % ¦ ¢
%SYSEXEC, %TSO, and %CMS
The %SYSEXEC, %TSO, and %CMS macro statements enable you to issue a host environment command.
%SYSGET
On some host environments, the %SYSGET function returns the value of host environment variables and symbols.
SYSPARM=
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.
SASMSTORE=
The SASMSTORE= system option specifies the location of stored compiled macros.
SASAUTOS=
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.
Host-Specific Macro Variables for z/OS
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
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.