BookmarkSubscribeRSS Feed
msf2021
Fluorite | Level 6

Hi,

 

I have the following code:

%let anomes_execucao = 202212;
%let min_maturidade = 2;

%put MIN_MATURIDADE=&MIN_MATURIDADE anomes_execucao=&anomes_execucao;

%if &min_maturidade eq . %then %do;
%let anomes_execucao=&anomes_execucao;
%put &=anomes_execucao;
%end;
%else %do;

%let year = %substr(&anomes_execucao,1,4);
%let month = %substr(&anomes_execucao,5,2);

%let new_month = %eval(&month - &min_maturidade);

%if &new_month > 12 %then %do;
%let year = %eval(&year + 1);
%let new_month = %eval(&new_month - 12);
%end;
%else %if &new_month < 1 %then %do;
%let year = %eval(&year - 1);
%let new_month = %eval(&new_month + 12);
%end;
%else %do;
%end;

%let anomes_execucao = %sysfunc(putn(&year*100 + &new_month, best6.));
%put &=anomes_execucao;
%end;

but i am getting this errors:

 

     %if &min_maturidade eq . %then %do;
32         %let anomes_execucao=&anomes_execucao;
33         %put &=anomes_execucao;
34         %end;
35         %else %do;
36         
37         %let year = %substr(&anomes_execucao,1,4);
38         %let month = %substr(&anomes_execucao,5,2);
39         
40         %let new_month = %eval(&month - &min_maturidade);
41         
42         %if &new_month > 12 %then %do;
ERROR: Nesting of %IF statements in open code is not supported. %IF ignored.
ERROR: Skipping to next %END statement.
43         %let year = %eval(&year + 1);
44         %let new_month = %eval(&new_month - 12);
45         %end;
46         %else %if &new_month < 1 %then %do;
ERROR: The %ELSE statement is not valid in open code.
47         %let year = %eval(&year - 1);
48         %let new_month = %eval(&new_month + 12);
49         %end;
ERROR: The %END statement is not valid in open code.
50         %else %do;
ERROR: The %ELSE statement is not valid in open code.
2                                                          The SAS System                             11:44 Thursday, April 27, 2023

51         %end;
ERROR: The %END statement is not valid in open code.
52         
53         %let anomes_execucao = %sysfunc(putn(&year*100 + &new_month, best6.));
54         %put &=anomes_execucao;
ANOMES_EXECUCAO=202210
55         %end;
ERROR: The %END statement is not valid in open code.
56         

Can anyone help me understand what is wrong with my code?

 

Thanks!

 

2 REPLIES 2
Patrick
Opal | Level 21

The rather new open code macro syntax option is really only for basic things.

Wrap your code into a macro. That's imho also better because it keeps many of your macro variables within local scope and though doesn't "pollute" your session. 

If you need a macro variable outside of the macro then make it explicitly global via %global statement.

%macro sample(
  anomes_execucao = 
  ,min_maturidade = 
  );
  %put MIN_MATURIDADE=&MIN_MATURIDADE anomes_execucao=&anomes_execucao;
  %if &min_maturidade eq . %then
    %do;
      %let anomes_execucao=&anomes_execucao;
      %put &=anomes_execucao;
    %end;
  %else
    %do;
      %let year = %substr(&anomes_execucao,1,4);
      %let month = %substr(&anomes_execucao,5,2);
      %let new_month = %eval(&month - &min_maturidade);

      %if &new_month > 12 %then
        %do;
          %let year = %eval(&year + 1);
          %let new_month = %eval(&new_month - 12);
        %end;
      %else %if &new_month < 1 %then
        %do;
          %let year = %eval(&year - 1);
          %let new_month = %eval(&new_month + 12);
        %end;
      %else
        %do;
        %end;

      %let anomes_execucao = %sysfunc(putn(&year*100 + &new_month, best6.));
      %put &=anomes_execucao;
    %end;
%mend;
%sample(
  anomes_execucao = 202212
  ,min_maturidade = 2
  );

 

Quentin
Super User

@Patrick's solution to put your code into an actual macro is correct.

 

But if I'm understanding what you're doing, you're basically taking a date and trying to increment or decrement it by some number of months.  In your code, you're doing it 'by hand' by treating the year and month as two different integers.  But SAS knows how to work with dates, and has a function, INTNX, which will add a month to a date.  It's generally easier (and safer) to let SAS do date calculations rather than write your own.

 

You can even use the macro language to call the INTNX function.  The code gets a bit ugly.  But basically, you use the INPUTN function to convert the string 202212 to a SAS date (22980 = 01Dec2022), then use INTNX to increment that date by 2 months (01Feb2023), then use PUTN to format that date as 202302.

 

%let anomes_execucao = 202212;
%let min_maturidade = 2;

%let anomes_execucao_want= %sysfunc(putn(%sysfunc(intnx(month,%sysfunc(inputn(&anomes_execucao,yymmn6)),&min_maturidade)),yymmn6)) ;

returns:

1    %let anomes_execucao = 202212;
2    %let min_maturidade = 2;
3
4    %let anomes_execucao_want=
4  ! %sysfunc(putn(%sysfunc(intnx(month,%sysfunc(inputn(&anomes_execucao,yymmn6)),&min_maturidade)),yy
4  ! mmn6)) ;
5    %put &=anomes_execucao_want ;
ANOMES_EXECUCAO_WANT=202302

 

The Boston Area SAS Users Group is hosting free webinars!
Next webinar will be in January 2025. Until then, check out our archives: https://www.basug.org/videos. And be sure to subscribe to our our email list.

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 2 replies
  • 3346 views
  • 11 likes
  • 3 in conversation