As the first step in the decommissioning of the site has been converted to read-only mode.

Here are some tips for How to share your SAS knowledge with your professional network.

Macro Language Wish List

From sasCommunity
Revision as of 12:15, 28 December 2017 by Paulkaefer (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
This is a work in progress. You can contribute to this article.

The following are thoughts and discussions from various SAS Macro Language users on topics in the macro language. The emphasis is on options or capabilities that could be added to the language that would increase its usability. How can the implementation of various options and statements be expanded or improved? If you have suggestions or alternatives, please add them here.

You may also want to add any suggestions as a SASware Ballot idea in the SAS Communities Forums. Other forum members can vote on the ideas, and there is visibility from SAS employees.

READONLY Macro Variables

The ability to protect our macro variables has been a long standing desire and SAS9.4 introduced the READONLY option on the %GLOBAL and %LOCAL statements.

The problem

There are caveats on the usage of the READONLY option.

Currently if the READONLY option is used, a second instance of that macro variable cannot be created. In the code shown here the macro %TRYIT will fail.

%global/readonly dsn=clinics;
%macro tryit;
%local dsn;
%* does other stuff;
%mend tryit;
%* The macro %TRYIT will fail;

Sample Use Cases

As referenced above there are several caveats with the idea of read only macro variables. Included below are several use cases where readonly macro variables could be considered a good approach/best practice.

Allow multiple instances of macro variables where one or more of the instances is read only

One use case for this functionality is that quite often a macro might need to access the value of a global macro variable, but then make a local copy. Currently that is done by creating a parameter and perhaps having the calling macro pass the value in. An alternative might be to allow a macro to create a local instance (also perhaps as READONLY) and have it inherit the value from a parent SYMBOL table.

Loading System Level Parameters from a Data Set

The use of data driven techniques has long been used in SAS applications. Loading application level parameters from a SAS data set is commonly done. Supporting a way to define and load READONLY macro variables for such values would be desirable. There are several problems with the current syntax/approach:

  1. They can only be specified in a %GLOBAL (or %LOCAL) statement. Ideally one would want to be able to use the SYMPUT (or SYMPUTX Function to do this.
  2. There are a number of characters that can't be specified as part of the default value.
    %global/readonly parm1=%str(contains a ; semicolon);
    produces this error:
    ERROR 180-322: Statement is not valid or it is used out of proper order.
    This limitation also prevents the loading of values from a data set via the use of CALL EXECUTE.

Assignment of Macro Variables to Specific Symbol Tables

Assignment of macro variables to symbol tables can follow a set of fairly arcane rules. Although a modicum of control can be achieved through the use of the %GLOBAL and %LOCAL statements, this level of control is often not sufficient.

The Problem

The application of table assignment rules can be unknowable during macro execution.

Sample Use Cases

It would be nice if we write a macro variable into any specific symbol table based on the symbol table name.

Possible Solutions

Instead of only the %GLOBAL and %LOCAL statements for a symbol table associated with the %ABC macro

%SYMTABLE ABC /assign=dsn;

would place &DSN in the symbol table for %ABC.

An alternative for the %LET statement could be something like:

%let ABC.dsn=clinics;

Allow / Control Flow of Macro Variable Assignment

Allow a macro variable assignment to flow to the next higher symbol table.

The Problem

Macros that mimic macro functions can return a single value. It is more complicated to write values from a macro into the symbol table of the calling macro (the next higher symbol table). We can do this now by predefining the macro variable in the higher table, but it would nice to be able to route it there directly.

Sample Use Cases

A statement that assigns a macro variable to the next higher symbol table.

%let dsn(1)=clinics;

where the (1) indicates one higher table.

Option to Force SQL Macro Variables to be Local

The Problem

Macro variables created using PROC SQL and the INTO: follow the arcane symbol table assignment rules, with no direct way to control symbol table assignment.

Sample Use Cases

Add the ability to force the variables to be local. Much like the third argument in the SYMPUTX routine.

Control the Search Order for Stored Compiled Macro Libraries

Currently the macro library search order is

  1. work.sasmacro
  2. mylib.sasmacro (when stored compiled macro libraries are used)
  3. autocall macro libraries

The Problem

There is no way to change the search order.

Sample Use Cases

If we have validated macros in a stored compiled library, we would like that library searched first in order to guarantee that the validated macro has been executed.

Allow the Creation of READONLY Macro Definitions

The Problem

There is only a limited ability to protect a macro from being re-engineered.

Sample Use Cases

Once a macro has been validated, it may need to be protected from either intentional or unintentional change. Using the stored compiled macro library with the ENCRYPT option offers some protection. Password protection options for catalog entries similar to those used with data sets would be helpful.