There are times when you need to dynamically obtain the data type and length of a SAS data set column. This occurred for me when I was writing a generic post process following a proc means with a conditional class statement. I need to know the data type and length of the class variable so that it can be assigned in the ATTRIB statement.
The below code utilizes the %isblank macro function that can be found here. The results of the function will be a dollar sign ($) if it is a character data type followed by the length of the data set column.
The table reveals the various results of calling this macro:
| Call | Result | Message |
|---|---|---|
| %columnlength(dsn=class, column = age); | 8 | |
| %columnlength(dsn=class, column = name); | $8 | |
| %columnlength(dsn=classx, column = name); | ERROR: The data set classx does not exist. | |
| %columnlength(dsn=class); | ERROR: You must pass in a value for column. | |
| %columnlength(dsn=class, column = namex); | ERROR: Could not find column: namex |
Here is an example of how I used this. I have a macro that includes a proc means/summary with a conditional class statement. After the process is finished I want to control the formatting, order and even add a new column. So this is my code snippet
data &dsn;
attrib
yyyymm length = $6
%if not %isblank(&classvar( %then %do;
&classvar length = %columnlength( dsn = &dsn, column = &classvar)
%end;
...
%macro columnlength(
dsn =
, column =
);
%local
dsid
position
type
retval
;
%if not %sysfunc(exist(&dsn)) %then %do;
%put %str(E)RROR: The data set &dsn does not exist.;
%return;
%end;
%if %isblank(&column) %then %do;
%put %str(E)RROR: You must pass in a value for column.;
%return;
%end;
%let dsid = %sysfunc(open(&dsn.));
%if &dsid %then %do;
%let position = %sysfunc(varnum(&dsid, &column));
%if &position = 0 %then %put %str(E)RROR: Could not find column: &column.;
%else %do;
%if %sysfunc(vartype(&dsid, &position)) = C %then %let type = $;
%let retval = &type%sysfunc(varlen(&dsid, &position));
%end;
%let dsid = %sysfunc(close(&dsid));
%end;
&retval
%mend;
No comments:
Post a Comment