Hi,
I have a problem. I import a macro variable named P from a table. P is a date, ex in my case :01JAN2017
I also import another macro variable named D. D is a number, or can be empty or missing.
I want to do this in my macro:
%if "&D." ne . %then %do; %if "&D." ne '' %then %do; %let &P. = intnx('month',today(),&D.-1,"BEGINNING"); %end; %end;
And I have a mistake:
ERROR: Expecting a variable name after %LET. ERROR: Symbolic variable name 01JAN2017 must begin with a letter or underscore.
Can you help me to correect this, i can't understand
Thanks in advance. 🙂
Just looking at the code (not able to run it at the moment), on the surface it looks like you just need to change:
to
Why do you have two if statements doing the same thing? Why are you putting data in macro variables? Why are you doing data processing in macro language? To answer your specific question requires a little debugging, which if your using macro you should know very well. Macro is a text find/replace system, nothing more. So if you do that on:
%let &P. = intnx('month',today(),&D.-1,"BEGINNING");
What you get in Base SAS - which is the actual programming language is:
%let 01JAN2017 = intnx('month',today(),01JAN2017-1,"BEGINNING");
Which you can clearly see is invalid SAS code, variables - and macro - have to start with a non-numeric character.
In any event the code given doesn't make much sense. Why would you want a macro variable, and all that macro logic to increment a date by one day? Simply doing:
%let p=01JAN2017; data want; set have; where date > "&P."d + 1; run;
Far simpler. The text p gets replaced in the code to create acurate Base SAS code.
&P. resolves to the value of macro variable P, so your %let statement becomes
%let 01JAN2017 = intnx('month',today(),&D.-1,"BEGINNING");
Since SAS names cannot start with a digit, this fails. I guess you wanted to do
%let P = ....
I also question your logic here, as you assign a complete function call to your presumed macro variable P. P will not resolve to a date, but to the text
intnx('month',today(),2-1,"BEGINNING");
(supposing macro variable D contains 2), which might or might not work once you use &P. anywhere in SAS code.
If you want to calculate a date, I suggest you do so in a data step and save the resulting value to a macro variable with call symput. See Maxim 11.
Ok, to just to be clear what you are trying to achieve:
So how to check what's in D.. I used the ANYDIGIT() function.. The only fiddly bit was having nested %SYSFUNC() macro functions in the final calculation..
%macro MyAdjust(P_Old,D);
%local P_New;
%if %sysfunc(anydigit(%str(&d))) %then %let P_New = %sysfunc(intnx(month,%sysfunc(today()),&D.-1,BEGINNING),date9.);
%put P_Old:&P_Old P_New:&P_New;
%mend;
%MyAdjust(01JAN2017,1);
%MyAdjust(01JAN2017,0);
%MyAdjust(01JAN2017,12);
%MyAdjust(01JAN2017,.);
%MyAdjust(01JAN2017,);
It just won't work for negative values of D because the negative sign counts as non-digit.
Many thanks Andrew,
That is what I need.
But unfortunately D is almost everytime negative 😞
Do you know how could I do to manage it?
I found this
%let P = %sysfunc(inputn(%sysfunc(putn(%sysfunc(intnx(month,%sysfunc(today()),&D.-1,B)),z6.)),DDMMYYN10));
in my mailbox.
Apart from the fact that it creates a raw value instead of a formatted date (which was expected), it looks like a serious attempt of someone who gets a kick out of hurting him/herself.
It violates several Maxims, notably Maxim 12 and parts of Maxim 11.
It is a bear to type correctly (at which it failed anyway), is hard to read for the next maintainer, and hard to debug.
Instead do
data _null_;
mydate = intnx(month,today(),&D.-1,"b");
call symputx('P',put(mydate,best.),'g');
run;
and use macro variable P directly, without "&P."d. (where somedate <= &P.)
You may also not be testing what you think you are with this line:
%if "&D." ne . %then %do;
Please check the log after running this code to see a demonstration.
%macro dummy (d); %if "&D." ne . %then %do; %put D was &d when not equal to .; %end; %else %do; %put D was &d when equal to .; %end;%mend; %dummy(d); %dummy( ); %dummy(.); %macro dummy2 (d); %if &D. ne . %then %do; %put D was &d when not equal to .; %end; %else %do; %put D was &d when equal to .; %end; %mend; %dummy2(d); %dummy2( ); %dummy2(.);
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!
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.