DATA Step, Macro, Functions and more

Macro within a macro

Accepted Solution Solved
Reply
Super Contributor
Posts: 619
Accepted Solution

Macro within a macro

How to execute a macro within a macro? Appreciate if someone give one example.


Accepted Solutions
Solution
‎08-18-2016 08:39 AM
Super User
Super User
Posts: 7,849

Re: Macro within a macro

[ Edited ]

You can call a macro within a macro.  Here is a trivial example.

 

%macro one(dsn);
proc print data=&dsn; run;
%mend one;
%macro two(dslist);
%local  i;
%do i=1 %to %sysfunc(countw(&dslist));
  %one(%scan(&dslist,&i));
%end;
%mend two;

%two(sashelp.class sashelp.cars);

 You can even call the same macro recursively.  Just make sure that the recursion ends.

View solution in original post


All Replies
Super User
Super User
Posts: 9,211

Re: Macro within a macro

Right, top question again.  Why?  There is rarely a need to use macros at all, and there is less reason to ever put macros within macros.  Remember macros generate text, nothing more, that text should be Base SAS code which gets executed.  If your doing coding then work in Base SAS, later on if there are repeating code blocks change them to macro.  There is never ever a need to create macro code to replace Base SAS coding.  Technically you can use %<macro name>; and &<macro variable> much like you can anywhere else, though if you don't know what you are doing you will just create problems for yourself.  

If you provide exmaples of your input data (datastep), and what you want to do I can show how to do it in Base SAS.

SAS Super FREQ
Posts: 9,257

Re: Macro within a macro

Hi:

   One possible reason to use a macro invocation call inside another macro call is to isolate code and make it re-usable. For example, in the 3 macro definitions below,

macro_examp.png

 

There are 3 macro definitions: %dodaily, %doonce and %wkrept. Of course, the code in %dodaily and %doonce is very simple and could instead represent more complicated processes. However, both %dodaily and %doonce are invoked inside the %wkrept macro program. The final invocation %wkrept will cause the other two macro programs to be retrieved, expanded and appropriate code generated by the macro processor. It is still all generating code. This approach however, especially if the macro definitions are stored in an autocall or compiled macro library would allow people who only want the  steps in %dodaily to just run that macro and people who only want the steps in %doonce to just run that macro and people who need the more complicated logic an use the %wkrept and pick the day they want the %doonce code to be used by specifying a parameter for &want.

 

  Working this way, the code is isolated. Each macro program can be maintained separately if necessary and invoked separately, allowing flexibility in using the code. And although the same type of flexibility might be provided with %include functionality, many sites prefer autocall macro programs and/or stored compiled macro programs for the added security and central storage location, accessible to everyone.

 

cynthia

Solution
‎08-18-2016 08:39 AM
Super User
Super User
Posts: 7,849

Re: Macro within a macro

[ Edited ]

You can call a macro within a macro.  Here is a trivial example.

 

%macro one(dsn);
proc print data=&dsn; run;
%mend one;
%macro two(dslist);
%local  i;
%do i=1 %to %sysfunc(countw(&dslist));
  %one(%scan(&dslist,&i));
%end;
%mend two;

%two(sashelp.class sashelp.cars);

 You can even call the same macro recursively.  Just make sure that the recursion ends.

Occasional Contributor
Posts: 6

Re: Macro within a macro

Hi,

 

I am giving &cpd value externally. For suppose I am doing

 

%let cpd=50; to run the macro.

 

I am getting the below error:

 

Line generated by the invoked macro "LOADCPDDATA".
3 select CPDCOBRS_RTRN_VLU_1 into :&FieldName
3 ! from cpdlogic where CPDCOBRS_GRP_T=&Group; quit;
--------
22
76
ERROR 22-322: Syntax error, expecting one of the following: ',', -, FROM, SEPARATED, THROUGH,
THRU, TRIMMED.

ERROR 76-322: Syntax error, statement will be ignored.

Occasional Contributor
Posts: 6

Re: Macro within a macro

libname loaddata 'C:\Users\lidpupm\Desktop\Provider Directory\Modular_configuration';


data cpdlogic (sortedby=CPDCOBRS_VAR_NM CPDCOBRS_GRP_T);
 set loaddata.cpdlogic;
	 if CPDCOBRS_CATG_T='CPD_logic' then do;
		FieldCounterChar = left(put(_n_,6.));
		FieldCounter = _n_;
		output;
		end;
		run;

		proc sql noprint;
		select max(FieldCounter) into :TotalFieldCount
		from cpdlogic ;
		quit;
		%put &TotalFieldCount;

		
%global &FieldName;
	%macro LoadCPDData (Group,Field_Num);
		 proc sql noprint; 
	        select CPDCOBRS_VAR_NM into :FieldName
			from cpdlogic
			where CPDCOBRS_GRP_T=&Group
	  		  and FieldCounter=&Field_Num;
		  quit; 

		  
	%put [&Field_Num];

			proc sql noprint;
			select CPDCOBRS_RTRN_VLU_1 into :&FieldName 
			from cpdlogic 
			where CPDCOBRS_GRP_T=&Group;
		quit;	
    %mend LoadCPDData;

	
	%macro loading;
	%if &TotalFieldCount > 1 %then %do;
	%do i=1 %to &TotalFieldCount;
		%LoadCPDData(&cpd,&i);
	%end;
	%end;
	%mend loading;

		

	%macro UnLoadCPDData (Group,Field_Num);
		 proc sql noprint; 
	        select 
	 			CPDCOBRS_VAR_NM into :FieldName
			from cpdlogic
			where CPDCOBRS_GRP_T=&Group
	  		  and FieldCounter=&Field_Num
			;
		  quit; 
 
	%put &Field_Num;

	%global &FieldName;
	
		proc sql noprint;
			select 
			' ' into :&FieldName 
			from cpdlogic 
			where CPDCOBRS_GRP_T=&Group
		;
		quit;	
    %mend UnLoadCPDData;

	options mlogic;
	%macro unloading;
	%if &TotalFieldCount > 1 %then %do;
	%do i=1 %to &TotalFieldCount;
		%UnLoadCPDData(&cpd,&i);
	%end;
	%end;
	%mend unloading;

	/*****END**********/

	

Hi,

 

I am giving &cpd value externally. For suppose I am doing

 

%let cpd=50; to run the macro.

 

I am getting the below error:

 

Line generated by the invoked macro "LOADCPDDATA".
3 select CPDCOBRS_RTRN_VLU_1 into :&FieldName
3 ! from cpdlogic where CPDCOBRS_GRP_T=&Group; quit;
--------
22
76
ERROR 22-322: Syntax error, expecting one of the following: ',', -, FROM, SEPARATED, THROUGH,
THRU, TRIMMED.

ERROR 76-322: Syntax error, statement will be ignored.

Super User
Super User
Posts: 7,849

Re: Macro within a macro

Your code seems incomplete as there are no calls to execute any of the macro definitions.

 

☑ This topic is solved.

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

Discussion stats
  • 6 replies
  • 8019 views
  • 12 likes
  • 5 in conversation