Search code examples
sasrow

Calling macros from within a datastep


Maintaining somebody else's SAS project, I found some code snippet which creates a table input-stats within a data step. The variable &all. contains a list of tables to examine. The data step is rather long which I shortened here with /* more code */:

%let all = "work.table1*mywork.table2";
   
   data input-stats;
      i = 1;      
      do while (scan(&all., i, '*') ne ''); 
      name = scan(&all., i, '*');  
      /* more code */
      output;
      i = i + 1;
    end;
   run;

I want to expand the table input-stat with yet another column giving me the number of lines of each table. I found the following macro within the project to do exactly this:

   %macro count_rows(ds);
      %let DSID=%sysfunc(OPEN(&DS.,IN));
      %let NOBS=%sysfunc(ATTRN(&DSID.,NOBS));
      %let RC=%sysfunc(CLOSE(&DSID.));
      &nobs
   %mend;

I would like to now integrate this call within the above mentioned data step, but obviously, I cannot just simply add a rows=%count_rows(name) (e.g. instead of /* more code */) as I would in other programming languages.

How would you solve this issue with minimal code modifications? Is there a way without making a huge %while loop?


Solution

  • The functionality of the macro code can be replicated in DATA Step scope by invoking the same functions. No need for macro and intermingling scopes that can be confusing when using RESOLVE or CALL EXECUTE.

    ...
          name = scan(&all., i, '*');  
          /* more code */
    
    * add row counting code here;
    _dsid = open (name,'IN');
    nobs = attrn(_dsid,'NOBS');
    _dsid = close (_dsid);
    drop _:;
    
          output;
    ...