<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Call Macro in a Macro in SAS Enterprise Guide</title>
    <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/889780#M43494</link>
    <description>&lt;P&gt;Hi all, seeking help on how to write a macro to call another macro for different period.&lt;BR /&gt;I have different setting to run each month. Im wondering can I write a macro to auto repeat run the same macro.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;%macro repeat(n);
	%do i = 1 %to &amp;amp;n.;
		%if &amp;amp;i. = 1 %then 
			%do;
				%let month 	= 4;
				%let lag 	= 2;
			%end;
		%if &amp;amp;i. = 2 %then 
			%do;
				%let month 	= 7;
				%let lag 	= 2;
			%end;
		%if &amp;amp;i. = 3 %then 
			%do;
				%let month 	= 4;
				%let lag 	= 1;
			%end;&lt;BR /&gt;
		%month_setting;
		%setting;
	%end;
%mend;
%repeat(3); 

%macro month_setting;
    %global begin end;
	%if %sysevalf(&amp;amp;lag = 2) %then
		%do;
			%let begin 		= "%sysfunc(intnx(month,%sysfunc(inputN(&amp;amp;period.01,yymmdd10.)),-&amp;amp;month.),date9.)"d;
			%let end 		= "%sysfunc(intnx(month,%sysfunc(inputN(&amp;amp;period.01,yymmdd10.)), +&amp;amp;lag.),date9.)"d;
		%end;
	%else %if %sysevalf(&amp;amp;lag = 1) %then 
		%do;
			%let begin 		= "%sysfunc(intnx(month,%sysfunc(inputN(&amp;amp;period.01,yymmdd10.)),-&amp;amp;month.+1),date9.)"d;
			%let end 		= "%sysfunc(intnx(month,%sysfunc(inputN(&amp;amp;period.01,yymmdd10.)), +&amp;amp;lag.+1),date9.)"d;
		%end;		
	%let end_YM 	= %sysfunc(inputn(%sysfunc(substr(%sysfunc(putn(&amp;amp;end., yymmddn8.)),1, 6)), 6.));
	%let beg_YM 	= %sysfunc(inputn(%sysfunc(substr(%sysfunc(putn(&amp;amp;begin., yymmddn8.)),1, 6)), 6.));

%mend;
&lt;BR /&gt;/*macro sample*/
%macro setting;
	Data working.M&amp;amp;Month._Setting;
		month 	= &amp;amp;month.;
		lag 	= &amp;amp;lag.;
		begin	= put(&amp;amp;begin.,yymmddn8.);
		end 	= put(&amp;amp;end.,yymmddn8.);
	run;
%mend;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 18 Aug 2023 01:39:07 GMT</pubDate>
    <dc:creator>Michelle_</dc:creator>
    <dc:date>2023-08-18T01:39:07Z</dc:date>
    <item>
      <title>Call Macro in a Macro</title>
      <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/889780#M43494</link>
      <description>&lt;P&gt;Hi all, seeking help on how to write a macro to call another macro for different period.&lt;BR /&gt;I have different setting to run each month. Im wondering can I write a macro to auto repeat run the same macro.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;%macro repeat(n);
	%do i = 1 %to &amp;amp;n.;
		%if &amp;amp;i. = 1 %then 
			%do;
				%let month 	= 4;
				%let lag 	= 2;
			%end;
		%if &amp;amp;i. = 2 %then 
			%do;
				%let month 	= 7;
				%let lag 	= 2;
			%end;
		%if &amp;amp;i. = 3 %then 
			%do;
				%let month 	= 4;
				%let lag 	= 1;
			%end;&lt;BR /&gt;
		%month_setting;
		%setting;
	%end;
%mend;
%repeat(3); 

%macro month_setting;
    %global begin end;
	%if %sysevalf(&amp;amp;lag = 2) %then
		%do;
			%let begin 		= "%sysfunc(intnx(month,%sysfunc(inputN(&amp;amp;period.01,yymmdd10.)),-&amp;amp;month.),date9.)"d;
			%let end 		= "%sysfunc(intnx(month,%sysfunc(inputN(&amp;amp;period.01,yymmdd10.)), +&amp;amp;lag.),date9.)"d;
		%end;
	%else %if %sysevalf(&amp;amp;lag = 1) %then 
		%do;
			%let begin 		= "%sysfunc(intnx(month,%sysfunc(inputN(&amp;amp;period.01,yymmdd10.)),-&amp;amp;month.+1),date9.)"d;
			%let end 		= "%sysfunc(intnx(month,%sysfunc(inputN(&amp;amp;period.01,yymmdd10.)), +&amp;amp;lag.+1),date9.)"d;
		%end;		
	%let end_YM 	= %sysfunc(inputn(%sysfunc(substr(%sysfunc(putn(&amp;amp;end., yymmddn8.)),1, 6)), 6.));
	%let beg_YM 	= %sysfunc(inputn(%sysfunc(substr(%sysfunc(putn(&amp;amp;begin., yymmddn8.)),1, 6)), 6.));

%mend;
&lt;BR /&gt;/*macro sample*/
%macro setting;
	Data working.M&amp;amp;Month._Setting;
		month 	= &amp;amp;month.;
		lag 	= &amp;amp;lag.;
		begin	= put(&amp;amp;begin.,yymmddn8.);
		end 	= put(&amp;amp;end.,yymmddn8.);
	run;
%mend;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 18 Aug 2023 01:39:07 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/889780#M43494</guid>
      <dc:creator>Michelle_</dc:creator>
      <dc:date>2023-08-18T01:39:07Z</dc:date>
    </item>
    <item>
      <title>Re: Call Macro in a Macro</title>
      <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/889784#M43495</link>
      <description>&lt;P&gt;Did you try the code?&amp;nbsp; Did it work?&amp;nbsp; If not what was wrong?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You can call another macro inside a macro.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;But you have to have defined it before you try to CALL it.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So make sure to move the call to %REPEAT() to after the definition of all three macros.&lt;/P&gt;</description>
      <pubDate>Fri, 18 Aug 2023 03:17:09 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/889784#M43495</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2023-08-18T03:17:09Z</dc:date>
    </item>
    <item>
      <title>Re: Call Macro in a Macro</title>
      <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/890149#M43502</link>
      <description>&lt;P&gt;No error pop up.&amp;nbsp;&lt;BR /&gt;It only able to run one times.&amp;nbsp; I have write %repeat(3). But, it only able to run &amp;amp;i.= 1&lt;/P&gt;</description>
      <pubDate>Mon, 21 Aug 2023 06:16:33 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/890149#M43502</guid>
      <dc:creator>Michelle_</dc:creator>
      <dc:date>2023-08-21T06:16:33Z</dc:date>
    </item>
    <item>
      <title>Re: Call Macro in a Macro</title>
      <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/890151#M43503</link>
      <description>&lt;P&gt;Run your macro with&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;options mprint mlogic symbolgen;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;set and post the log.&lt;/P&gt;</description>
      <pubDate>Mon, 21 Aug 2023 06:39:09 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/890151#M43503</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2023-08-21T06:39:09Z</dc:date>
    </item>
    <item>
      <title>Re: Call Macro in a Macro</title>
      <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/890152#M43504</link>
      <description>&lt;P&gt;you can do it much simpler and much more readable using data step:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;libname working (work);

%macro setting(period, i);

data working.P&amp;amp;period._Setting;

  period = input(cats(symget('period'),'01'),yymmdd8.);
  i = symgetn("i");

  select(i);
    when(1) 
      do;
        month = 4;
        lag   = 2;
      end;
    when(2) 
      do;
        month = 7;
        lag   = 2;
      end;
    when(3) 
      do;
        month = 4;
        lag   = 2;
      end;
    otherwise put "ERROR: I should be in 1, 2, 3.";
  end;

  select(lag);
    when(2)
      do;
        b = intnx("month", period,-month);
        e = intnx("month", period, +lag);
      end;
    when(1)
      do;
        b = intnx("month", period,-month+1);
        e = intnx("month", period, +lag+1);
      end;
    otherwise put "ERROR: LAG shoild be  in 1, 2.";
  end; 

  begin	= put(b,yymmddn8.);
  end 	= put(e,yymmddn8.);


  /* you didnot used those 2 in the code at all */
	beg_YM 	= put(b,yymmn6.);
  end_YM 	= put(e,yymmn6.);




  keep month lag begin end beg_YM end_YM ;
run;

%mend;



%setting(202308, 1)
proc print;
run;

%setting(202308, 2)
proc print;
run;

%setting(202308, 3)
proc print;
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Bart&lt;/P&gt;</description>
      <pubDate>Mon, 21 Aug 2023 06:50:22 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/890152#M43504</guid>
      <dc:creator>yabwon</dc:creator>
      <dc:date>2023-08-21T06:50:22Z</dc:date>
    </item>
    <item>
      <title>Re: Call Macro in a Macro</title>
      <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/890160#M43506</link>
      <description>&lt;P&gt;Apologies. Can ignore the previous coding i asked. The issue seems like appear after the %datecreate macro.&amp;nbsp;&lt;BR /&gt;If only run until %setting then it works. However, when run one more macro (i.e. %datecreate) then it won't auto generate the second and third run.&amp;nbsp;&lt;BR /&gt;So, i have create delete specific global macro.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;%macro repeat(n);
	%do i = 1 %to &amp;amp;n.;
		%if &amp;amp;i. = 1 %then 
			%do;
				%let month 	= 4;
				%let lag 	= 2;
			%end;
		%if &amp;amp;i. = 2 %then 
			%do;
				%let month 	= 7;
				%let lag 	= 2;
			%end;
		%if &amp;amp;i. = 3 %then 
			%do;
				%let month 	= 4;
				%let lag 	= 1;
			%end;

		%month_setting;
		%setting;
		%datecreate;
		%deleteALL;
	%end;
%mend;
%repeat(3); 

%macro month_setting;
    %global begin end;
	%if %sysevalf(&amp;amp;lag = 2) %then
		%do;
			%let begin 		= "%sysfunc(intnx(month,%sysfunc(inputN(&amp;amp;period.01,yymmdd10.)),-&amp;amp;month.),date9.)"d;
			%let end 		= "%sysfunc(intnx(month,%sysfunc(inputN(&amp;amp;period.01,yymmdd10.)), +&amp;amp;lag.),date9.)"d;
		%end;
	%else %if %sysevalf(&amp;amp;lag = 1) %then 
		%do;
			%let begin 		= "%sysfunc(intnx(month,%sysfunc(inputN(&amp;amp;period.01,yymmdd10.)),-&amp;amp;month.+1),date9.)"d;
			%let end 		= "%sysfunc(intnx(month,%sysfunc(inputN(&amp;amp;period.01,yymmdd10.)), +&amp;amp;lag.+1),date9.)"d;
		%end;		
	%let end_YM 	= %sysfunc(inputn(%sysfunc(substr(%sysfunc(putn(&amp;amp;end., yymmddn8.)),1, 6)), 6.));
	%let beg_YM 	= %sysfunc(inputn(%sysfunc(substr(%sysfunc(putn(&amp;amp;begin., yymmddn8.)),1, 6)), 6.));

%mend;

/*macro sample*/
%macro setting;
	Data working.M&amp;amp;Month._Setting;
		month 	= &amp;amp;month.;
		lag 	= &amp;amp;lag.;
		begin	= put(&amp;amp;begin.,yymmddn8.);
		end 	= put(&amp;amp;end.,yymmddn8.);
	run;
%mend;


%macro datecreate;
	%global dif;
	%let dif = %sysfunc(intck(MONTH,&amp;amp;begin,&amp;amp;end)); 
		%do i= 1 %to &amp;amp;dif;
			%global date_&amp;amp;i;

			%let date_&amp;amp;i=%sysfunc(intnx(month,&amp;amp;begin,&amp;amp;i,B),yymmn6.);
			%put &amp;amp;&amp;amp;date_&amp;amp;i;
		%end;
%mend;


%macro deleteALL;
 
   	options nonotes;

  	%local vars;
 
  	proc sql noprint;
      	    select name into: vars separated by ' '
         	  from dictionary.macros
            	      where scope = 'GLOBAL' and (name contains 'DATE_' or name in ('MONTH', 'LAG', 'BEGIN','END', 'BEG_YM', 'END_YM', 'DIF'));
   	quit;

   	%symdel &amp;amp;vars;
 
   	options notes;
 
    	%put NOTE: Macro variables deleted.;
 
%mend;

&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;But, the above coding not working also. It didn't pop any errors. However, it will not generate the results for Month 7&amp;nbsp; + Lag 2 and Month 4 + lag 1.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 21 Aug 2023 08:50:13 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/890160#M43506</guid>
      <dc:creator>Michelle_</dc:creator>
      <dc:date>2023-08-21T08:50:13Z</dc:date>
    </item>
    <item>
      <title>Re: Call Macro in a Macro</title>
      <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/890171#M43507</link>
      <description>&lt;P&gt;Sloppy macro programming. Always (as in&amp;nbsp;&lt;U&gt;&lt;STRONG&gt;ALWAYS&lt;/STRONG&gt;&lt;/U&gt;) define variables used in the macro as local (%LOCAL statement).&lt;/P&gt;
&lt;P&gt;Your macro datecreate uses i for the loop, which is also used in repeat; after returning from datecreate, &amp;amp;i will have a large enough value to terminate the loop in repeat.&lt;/P&gt;</description>
      <pubDate>Mon, 21 Aug 2023 11:25:37 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/890171#M43507</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2023-08-21T11:25:37Z</dc:date>
    </item>
    <item>
      <title>Re: Call Macro in a Macro</title>
      <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/890202#M43509</link>
      <description>&lt;P&gt;Kurt has identified the problem, I want to share an example.&amp;nbsp; Suppose you have macros OUTER and INNER where OUTER invokes INNER.&amp;nbsp; You want to have OUTER loop 2 times, and INNER loop 3 times per iteration of OUTER.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If you code it like:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro outer(n=) ;
  %do i=1 %to &amp;amp;n ;
    %put %nrstr(%%)&amp;amp;sysmacroname ;
    %put _user_ ;
    %put ;

    %inner(n=3) ;

  %end ;
%mend outer ;

%macro inner(n=) ;
  %do i=1 %to &amp;amp;n ;  
    %put %nrstr(%%)&amp;amp;sysmacroname ;
    %put _user_ ;
    %put ;
  %end ;
%mend inner ;

%outer(n=2)&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Your log will show that OUTER is loops once, not twice as intended.&amp;nbsp; This is the problem you're having:&lt;/P&gt;
&lt;PRE&gt;22   %outer(n=2)
%OUTER
OUTER I 1
OUTER N 2

%INNER
INNER N 3
OUTER I 1
OUTER N 2

%INNER
INNER N 3
OUTER I 2
OUTER N 2

%INNER
INNER N 3
OUTER I 3
OUTER N 2
&lt;/PRE&gt;
&lt;P&gt;When OUTER executes, it creates the macro variables i and N.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;When INNER executes, it creates a new macro variable N which is a different macro variable than the variable N which exists in outer.&amp;nbsp; It does this because N is defined as macro parameter to INNER.&lt;/P&gt;
&lt;P&gt;But when the %DO loop in INNER executes, it does NOT create a new macro variable i for INNER.&amp;nbsp; Instead it uses the macro variable i that already exists in OUTER. So this is a naming collision.&amp;nbsp; INNER has changed the values of a macro variable that belongs to OUTER.&amp;nbsp; And because INNER loops three times, you end up with the macro variable i having the value of 3.&amp;nbsp; Then the %DO loop in OUTER does not loop a second time, because i is already 3.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The way to avoid this problem is to declare the macro variable i to be local in INNER.&amp;nbsp; That way when INNER executes, the %LOCAL statement will create a new local macro variable i for INNER that is separate from the macro variable i in OUTER.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro outer(n=) ;
  %local i ;
  %do i=1 %to &amp;amp;n ;
    %put %nrstr(%%)&amp;amp;sysmacroname ;
    %put _user_ ;
    %put ;

    %inner(n=3) ;

  %end ;
%mend outer ;

%macro inner(n=) ;
  %local i;
  %do i=1 %to &amp;amp;n ;  
    %put %nrstr(%%)&amp;amp;sysmacroname ;
    %put _user_ ;
    %put ;
  %end ;
%mend inner ;

%outer(n=2)&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Log:&lt;/P&gt;
&lt;PRE&gt;22   %outer(n=2)
%OUTER
OUTER I 1
OUTER N 2

%INNER
INNER I 1
INNER N 3
OUTER I 1
OUTER N 2

%INNER
INNER I 2
INNER N 3
OUTER I 1
OUTER N 2

%INNER
INNER I 3
INNER N 3
OUTER I 1
OUTER N 2

%OUTER
OUTER I 2
OUTER N 2

%INNER
INNER I 1
INNER N 3
OUTER I 2
OUTER N 2

%INNER
INNER I 2
INNER N 3
OUTER I 2
OUTER N 2

%INNER
INNER I 3
INNER N 3
OUTER I 2
OUTER N 2
&lt;/PRE&gt;
&lt;P&gt;With that, outer loops two times, so you get the expected 2*3=6 executions of INNER.&amp;nbsp; And you can see in the log that the macro variables i and N in INNER are independent of the macro variables i and N in OUTER.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 21 Aug 2023 14:11:20 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Enterprise-Guide/Call-Macro-in-a-Macro/m-p/890202#M43509</guid>
      <dc:creator>Quentin</dc:creator>
      <dc:date>2023-08-21T14:11:20Z</dc:date>
    </item>
  </channel>
</rss>

