I was trying to find the difference between the two conditions below, the top one is running fine with TRUE result, but the bottom one always gave me a FALSE result
%let open_begin = '01APR2017'd;
%let open_end = '30JUN2017'd;
.../*top one*/
%else %if (&open_begin) ~= and &open_begin <= &open_end %then %do;
&open_begin <= OPENDATE <= &open_end
%end;
...
vs.
.../*bottom one*/
%else %if &open_begin > '01JAN1960'd and &open_end > '01JAN1960'd and &open_begin <= &open_end %then %do;
&open_begin <= OPENDATE <= &open_end
%end;
Any thoughts? Thanks.
Hello @wzca74 and welcome to the SAS Support Communities!
Basically, macro variables contain text. (Nevertheless, integer arithmetic can be done: see "How the Macro Processor Evaluates Arithmetic Expressions".) In particular, your date literals ('01APR2017'd etc.) are in fact treated as character strings.
Hence, the first comparison ("top one") yields TRUE accidentally because '0... is alphabetically smaller than '3... .
The "bottom one" yields FALSE because '01A... is alphabetically not greater than '01J... (first inequality).
To make those comparisons work, use the %SYSEVALF function, e.g.
... and %sysevalf(&open_begin <= &open_end) %then ...
And don't worry, you're not the first who had this problem: %If statement using dates.
Hello @wzca74 and welcome to the SAS Support Communities!
Basically, macro variables contain text. (Nevertheless, integer arithmetic can be done: see "How the Macro Processor Evaluates Arithmetic Expressions".) In particular, your date literals ('01APR2017'd etc.) are in fact treated as character strings.
Hence, the first comparison ("top one") yields TRUE accidentally because '0... is alphabetically smaller than '3... .
The "bottom one" yields FALSE because '01A... is alphabetically not greater than '01J... (first inequality).
To make those comparisons work, use the %SYSEVALF function, e.g.
... and %sysevalf(&open_begin <= &open_end) %then ...
And don't worry, you're not the first who had this problem: %If statement using dates.
Thanks FreelanceReinhard for the detailed explanation. It is great!
The macro language is a code generator, which only knows the datatype text, and cannot do calculations on its own, with the exception of integer arithmetic in %if and %do. Therefore the date literals are treated as strings in comparisons.
'01A is always "smaller" than '01J (in the collating sequence).
If you follow Maxim 28 and use raw values in the macro variables
%let open_begin = %sysfunc(inputn(20170401,yymmdd8.));
the comparisons will work as expected.
Thanks KurtBremser for the answer. Appreciated!
Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.
Register today!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.