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!
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
);
@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
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!
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.
Ready to level-up your skills? Choose your own adventure.