0
votes

I'm curious as to why some functions cannot interpret the character type of a macro variable correctly.

Here's a sample program

%let yymm = 1905;

data tst; 
reportDate = input(&yymm.,yymmn4.); 
run;

will produce a numeric value, reportDate, with a null associated with it.

But either of the following programs:

data tst;
reportDate = input("&yymm.",yymmn4.);
run;

data tst;
reportDate = input(put(&yymm.,4.),yymmn4.);
run;

will result in the correct value, 21670.

Since macro variables always resolve as characters, why can't the input function resolve the macro variable reference correctly? The first argument requires a character value, which the resolved reference &yymm. is. I've always been curious about this functionality.

2
Macro variables resolve as 'text' is a better way to think of it, and that text needs to be valid SAS code, which the above was not.Reeza

2 Answers

2
votes

Once the macro processor has finished doing its magic the generated SAS code is then acted on by SAS itself.

The reason that code like:

reportDate = input(1905,yymmn4.);

results in a missing value is explained by the NOTE that SAS writes to the LOG.

478   data tst;
479   reportDate = input(1905,yymmn4.);
480   run;

NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
      479:20

Because you used a number instead of character string for the first argument in the INPUT() function SAS converted it to a character string for you. When it does that it used the BEST12. format so you ended up with the string ' 1905' which starts with 8 blanks. Since you use a width of only 4 characters on your informat the result is a missing value. The last 8 characters of converted string is ignored.

The other two versions fix this by giving INPUT() a string value instead. Either by generating an actual string literal or using the PUT() function to convert the number to a string using a format that does not produce the leading spaces.

2
votes

Quote around the variable.

%let yymm = 1905;

data tst; 
reportDate = input("&yymm.",yymmn4.); 
run;

without quotes it's attempting to do this:

 data tst; 
    reportDate = input(1905,yymmn4.); 
 run;