BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Babloo
Rhodochrosite | Level 12

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

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

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

6 REPLIES 6
RW9
Diamond | Level 26 RW9
Diamond | Level 26

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.

Cynthia_sas
SAS Super FREQ

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

Tom
Super User Tom
Super User

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.

sai99
Calcite | Level 5

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.

sai99
Calcite | Level 5
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.

Tom
Super User Tom
Super User

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

 

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 6 replies
  • 57226 views
  • 15 likes
  • 5 in conversation