BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
benhaz
Calcite | Level 5

Hi ,

I am running this code but the output result I am getting in SAS log. I want these output in a sas dataset. 

Any solution will be appreciate.

 


%macro list_files(dir,ext);
%local filrf rc did memcnt name i;
%let rc=%sysfunc(filename(filrf,&dir));
%let did=%sysfunc(dopen(&filrf));

%if &did eq 0 %then %do;
%put Directory &dir cannot be open or does not exist;
%return;
%end;

%do i = 1 %to %sysfunc(dnum(&did));

%let name=%qsysfunc(dread(&did,&i));

%if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then %do;
%put &dir/&name;
%end;
%else %if %qscan(&name,2,.) = %then %do;
%list_files(&dir/&name,&ext)
%end;

%end;
%let rc=%sysfunc(dclose(&did));
%let rc=%sysfunc(filename(filrf));

%mend list_files;

 

%list_files(/sasdata/im_pic_sas,sas)

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

Instead of %PUTting things to the log, create statements (because creating code is what the macro processor is meant to do):

%macro list_files(dir,ext);
%local filrf rc did memcnt name i;
%let rc=%sysfunc(filename(filrf,&dir));
%let did=%sysfunc(dopen(&filrf));

%if &did eq 0 %then %do;
%put Directory &dir cannot be open or does not exist;
%return;
%end;

%do i = 1 %to %sysfunc(dnum(&did));

%let name=%qsysfunc(dread(&did,&i));

%if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then %do;
fname = "&dir/&name";
output;
%end;
%else %if %qscan(&name,2,.) = %then %do;
%list_files(&dir/&name,&ext)
%end;

%end;
%let rc=%sysfunc(dclose(&did));
%let rc=%sysfunc(filename(filrf));

%mend list_files;

and then use the macro in the proper place:

data myfiles;
length fname $200;
%list_files(your_path,sas)
run;

View solution in original post

4 REPLIES 4
PaigeMiller
Diamond | Level 26

The %PUT statement writes to the LOG. If you don't want this, then you need to re-write the macro so that the results go to a SAS data set. In fact, if you search these forums, you will find many examples of the code that will write this information to the SAS data set.

 

Also, see Maxim 23.

https://communities.sas.com/t5/SAS-Communities-Library/Maxims-of-Maximally-Efficient-SAS-Programmers...

--
Paige Miller
Kurt_Bremser
Super User

Instead of %PUTting things to the log, create statements (because creating code is what the macro processor is meant to do):

%macro list_files(dir,ext);
%local filrf rc did memcnt name i;
%let rc=%sysfunc(filename(filrf,&dir));
%let did=%sysfunc(dopen(&filrf));

%if &did eq 0 %then %do;
%put Directory &dir cannot be open or does not exist;
%return;
%end;

%do i = 1 %to %sysfunc(dnum(&did));

%let name=%qsysfunc(dread(&did,&i));

%if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then %do;
fname = "&dir/&name";
output;
%end;
%else %if %qscan(&name,2,.) = %then %do;
%list_files(&dir/&name,&ext)
%end;

%end;
%let rc=%sysfunc(dclose(&did));
%let rc=%sysfunc(filename(filrf));

%mend list_files;

and then use the macro in the proper place:

data myfiles;
length fname $200;
%list_files(your_path,sas)
run;
benhaz
Calcite | Level 5

Thank You Sir! This is working.

Appreciate your help!

Quentin
Super User

Another option is to add functionality to the macro so that you have the option of either writing to the log or creating an output dataset.

 

Within the macro, it would need to generate the full code for a DATA step.  With a recursive macro like this, it takes a bit more thinking.  Because on the first iteration only, you want it to start writing the DATA step.  Then on every iteration it outputs a record.  And at the end of the first iteration it ends the DATA step. 

 

Something like:

 

%macro list_files(dir,ext,out=);
  %local filrf rc did memcnt name i;
  %let rc=%sysfunc(filename(filrf,&dir));
  %let did=%sysfunc(dopen(&filrf));

  
  %*If out= was specified, and not one of the recursive calls, start writing a data step ;
  %if %superq(out) ne %str() and %sysmexecname(%sysmexecdepth - 1) ne LIST_FILES 
  %then %do;
    data &out ;
      length path $200 ; *Pick a longer length if you have longer paths ;
  %end;


  %if &did eq 0 %then %do;
    %put Directory &dir cannot be open or does not exist;
    %return;
  %end;

  %do i = 1 %to %sysfunc(dnum(&did));
    %let name=%qsysfunc(dread(&did,&i));
    %if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then %do;
      %put &dir/&name;

      %*Write the path to output dataset ;
      %if %superq(out) ne %str() %then %do ;
        path="&dir/&name" ;
        output ;
      %end ;
    %end;
    %else %if %qscan(&name,2,.) = %then %do;
      %list_files(&dir/&name,&ext)
    %end;
  %end;

  %*If out= was specified, and not one of the recursive calls, end the data step ;
  %if %superq(out) ne %str() and %sysmexecname(%sysmexecdepth - 1) ne LIST_FILES 
  %then %do;
    run ;
  %end;


  %let rc=%sysfunc(dclose(&did));
  %let rc=%sysfunc(filename(filrf));

%mend list_files;

options mprint ;
%list_files(/sasdata/im_pic_sas, sas, out=work.want)

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

Register Now

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 4 replies
  • 1985 views
  • 0 likes
  • 4 in conversation