How to execute a macro within a macro? Appreciate if someone give one example.
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.
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.
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,
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
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.
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.
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.
Your code seems incomplete as there are no calls to execute any of the macro definitions.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.