Zachary
Zachary

Reputation: 319

SAS Macro Variable Numeric But Char in another Macro?

I want to do simple math on numeric date, format YYYYMM, but when I run my monthend_add macro in another macro it changes it to character. Can anyone explain this?

/* macro to add months and keep YYYYMM format */
%Macro monthend_add(me, add);
     %let months = %eval(&me / 100 * 12 + %sysfunc(mod(&me, 100)) + &add - 1);
     %eval(&months / 12 * 100 + %sysfunc(mod(&months, 12)) + 1);
%mend monthend_add;

%let me = 201512;
%let me = %monthend_add(&me, 1);
%put me: &me, %datatyp(&me);


%macro now_char;
    %let me = 201512;
    %let me = %monthend_add(&me, 1);
    %put me: &me, %datatyp(&me);
%mend;

%now_char    

Upvotes: 1

Views: 270

Answers (1)

Allan Bowe
Allan Bowe

Reputation: 12691

In both cases (global scope in first, inner scope in second) you are returning the semicolon in your monthend_add macro. To fix remove this as follows:

%Macro monthend_add(me, add);
  %let months = %eval(&me / 100 * 12 + %sysfunc(mod(&me, 100)) + &add - 1);
  %eval(&months / 12 * 100 + %sysfunc(mod(&months, 12)) + 1)
%mend monthend_add; 

In the first instance, it seems the returned semicolon terminated your assignment statement. Hence &me=201512 and %datatype(201512)=NUMERIC.

In the second instance (within a macro) it seems this was not the case, and so &me=201512; and %datatyp(201512;)=CHAR

I would guess the reason is that in global context, the macro executes immediately before the assignment is finished (hence terminates itself at the first semicolon).

Whereas the in the second (inner macro) context, the monthend_add macro cannot be run until the now_char is called - hence when now_char is compiled, the space for the value of me is pre-allocated, into which the returned semicolon is then subsequently stored.

As a final note - remember that (technically) SAS macro variables only ever store text! 65,534 characters to be exact.

Upvotes: 2

Related Questions