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 (BASUG) is hosting our in person SAS Blowout on Oct 18!
This full-day event in Cambridge, Mass features four presenters from SAS, presenting on a range of SAS 9 programming topics. Pre-registration by Oct 15 is required.
Full details and registration info at https://www.basug.org/events.

SAS Innovate 2025: Call for Content

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!

Submit your idea!

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
  • 2981 views
  • 11 likes
  • 3 in conversation