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