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)
BASUG is hosting free webinars Next up: Mark Keintz presenting History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies on May 8. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

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