Pages

SyntaxHighlighter

Showing posts with label varlen. Show all posts
Showing posts with label varlen. Show all posts

Friday, September 14, 2018

ColumnLength macro function

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;