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

 

BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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.

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
  • 2 replies
  • 2435 views
  • 11 likes
  • 3 in conversation