Tiwtiw
Tiwtiw

Reputation: 495

Generate SAS macro code without executing it

Is there a way I can print the SAS code generated by a macro without executing it?

Thanks

Upvotes: 2

Views: 1427

Answers (4)

Tom
Tom

Reputation: 51591

You could try using PROC STREAM. Let's define a simple macro

%macro mymacro;
 proc print data=sashelp.class; run;
%mend;

Make a fileref to contain the resulting code

filename mycode temp;

Now you can use PROC STREAM to convert the macro call into text.

proc stream outfile=mycode; BEGIN
%mymacro
;;;;

It should work for any macro that does not need to make decisions based on the results of the code that it is generating.

Upvotes: 0

Allan Bowe
Allan Bowe

Reputation: 12691

Yet another approach, if your macro is mainly data step and proc sql, is to use the run cancel; and proc sql noexec; options, eg as follows:

%macro example(somelogic=1,execute=NO);

  %local cancel noexec;
  %if &execute=NO %then %do;
    %let cancel=cancel;
    %let noexec=noexec;
  %end;

  data some_ds;
    set some_other_ds;
  %if &somelogic %then %do;
    this=that;
  %end;
  run &cancel;

  proc sql &noexec;
  create table maybe as 
    select * from have;

%mend;

In this way your code will be generated / syntax checked but not executed.

Of course - this is a 'handle with care' approach as there are still many things that can still be changed within a macro context. @Chris Long is correct - there is no reliable way of generating the SAS code without executing it (as the actual code generated is often dependent on the result of earlier executions).

Upvotes: 2

Joe
Joe

Reputation: 63424

There are several ways to get to what you want, that work at least some of the time.

You can set options obs=0; and then run the macro (With MPRINT turned on). That will run the macro but won't process any rows of data. This will work for many macros; but it will overwrite datasets, so it's not safe if you care about whatever it's writing out over being preserved.

%macro do_something;
  data test;
    set sashelp.class;
  run;
%mend do_something;

options mprint;
options obs=0;

%do_something;

WORK.TEST was overwritten, note, but no observations were processed.

Now, if you're talking about a stored compiled macro (this seems the most useful scenario, no?), then it depends on how it was stored. If it was stored with the /source switch, then you can get the source back with %COPY.

libname sasdir "e:\temp"; 
options mstored sasmstore=sasdir; 

%macro do_something/store source;
  data test;
    set sashelp.class;
  run;
%mend do_something;

%copy do_something/source;

It requires it to have been compiled with the source flag, though. If it wasn't, then the source is unrecoverable short of running the code.

Upvotes: 4

Chris Long
Chris Long

Reputation: 1319

No, not in general. A macro is a program that generates SAS code, so the only way to know what code it's going to generate is to run it. In some very simple cases, you might be able to parse the macro and determine what SAS code will be generated, but for any more complex case, you'd have to re-implement a program to read, parse and execute a macro for this to work. See also the Halting Problem.

Upvotes: 1

Related Questions