Reputation: 319
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
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