Macro output issue

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 8
Accepted Solution

Macro output issue

Hi,

how can i get the "trt"  value from the macro below to be printed in %put statement..

 

%macro cnt(db=,n1=,n2=);

proc sql noprint;

  select count(disinct subjs) into: trt&n1 from &db where trtn=&n2;

quit;

%mend;

%cnt(db=dbs,n1=1,n2=1);

 

%put &trt;

 

Thank you,

New510


Accepted Solutions
Solution
‎03-13-2016 11:33 AM
Super User
Super User
Posts: 6,364

Re: Macro output issue

[ Edited ]

Whne you write to a macro variable SAS will use the the existing macro variable with that name. If no such macro variable exists then a new one is created in the current scope.  In this case that is within your macro %CNT() so the new TRT1 macro variable is defined as local to the macro %CNT() and so disappears once %CNT() finishes running. 

You can either create the macro variable before calling the macro,

 

%let trt1=UNKNOWN;
%cnt(db=dbs,n1=1,n2=1);
%put &=trt1;

or have the macro attempt to make it a global macro variable before writing to it.  Note that this will fail if the macro variable already exists as local to some running macro that is calling your %CNT() macro.  You can adjust for that by only making the macro variable global when it does not already exist.

%macro cnt(db=,n1=,n2=);
%if not %symexist(trt&n1) %then %global trt&n1;
proc sql noprint;
  select count(disinct subjs) into: trt&n1 from &db where trtn=&n2;
quit;
%mend;

  

View solution in original post


All Replies
Grand Advisor
Posts: 17,393

Re: Macro output issue

Macro variable scope. The macro variable is local, it exists within the macro, but does not exist outside of the macro. Change the scope to global.  

 

%global trt&n1;

As always the documentation is always helpful:

http://support.sas.com/documentation/cdl/en/mcrolref/62978/HTML/default/viewer.htm#p1b76sxg9dbcyrn1l...

 

 

Respected Advisor
Posts: 4,992

Re: Macro output issue

Well, there is no macro variable named TRT, nor a data set variable named TRT.  So you won't be able to print those.  

 

If you want to see the name and value of the macro variable being created by PROC SQL, the %PUT statement must be moved before the %MEND statement.  SQL always creates macro variables in the local symbol table, so the macro variable is gone by the time the macro ends.  

 

This statement (between QUIT and %MEND) should do the trick:

 

%put trt&n1 is &&trt&n1;

 

 

Solution
‎03-13-2016 11:33 AM
Super User
Super User
Posts: 6,364

Re: Macro output issue

[ Edited ]

Whne you write to a macro variable SAS will use the the existing macro variable with that name. If no such macro variable exists then a new one is created in the current scope.  In this case that is within your macro %CNT() so the new TRT1 macro variable is defined as local to the macro %CNT() and so disappears once %CNT() finishes running. 

You can either create the macro variable before calling the macro,

 

%let trt1=UNKNOWN;
%cnt(db=dbs,n1=1,n2=1);
%put &=trt1;

or have the macro attempt to make it a global macro variable before writing to it.  Note that this will fail if the macro variable already exists as local to some running macro that is calling your %CNT() macro.  You can adjust for that by only making the macro variable global when it does not already exist.

%macro cnt(db=,n1=,n2=);
%if not %symexist(trt&n1) %then %global trt&n1;
proc sql noprint;
  select count(disinct subjs) into: trt&n1 from &db where trtn=&n2;
quit;
%mend;

  

Esteemed Advisor
Esteemed Advisor
Posts: 7,232

Re: Macro output issue

Hi,

 

Whilst @Tom has provided a nice solution, I would question the purpose of this.  To achieve it it is breaking some general guidelines on macros such as encapsulation - i.e. defining and using variables within the scope they are used.  It can become difficult to maintain and debug.  Now I am guessing from your code that you are creating a macro variable for big or small N's.  As these are used throughout tables, you might consider a different approach.  In your start program create a dataset, then for each population/sub-group insert a row for that and the count:

proc sql;
  create table POPS (POP char(200),SUBGROUP char(200),N num);
  insert into POPS 
  set POP="Enrolled",
       SUBGROUP="",
       N=(select count(distinct SUBJID) from MYDATA);
quit;

The benfits of this system are several: code is simpler and easier to read, and easier to maintain.  You can also validate the populations counts separately.  This dataset can be used in all other tables ensuring the value remains constant.  

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 4 replies
  • 376 views
  • 2 likes
  • 5 in conversation