BookmarkSubscribeRSS Feed
Reeza
Super User

@GN0001 wrote:

Hello team,

I am not getting errors. I just asked if the macro access to the files in each path.

Regards,

BlueBlue


You would ask the author of the macro or developer of the macro that question. 

Example 2: List All Files within a Directory Including Subdirectories

https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/mcrolref/n0js70lrkxo6uvn1fl4a5aafnlgt.htm

 

Patrick
Opal | Level 21

@GN0001 wrote:

It gives errors.


WHAT error! SAS log please.

 

Patrick_0-1635199213014.png

 

And after "re-engineering the URL": https://www.pharmasug.org/proceedings/2015/QT/PharmaSUG-2015-QT23.pdf 

So you found this macro in some paper so it's definitely not SAS OOTB provided.

 

GN0001
Barite | Level 11

Hello team,

It doesn't matter it is from SAS docs or not. It takes care of some stuff.

Regards,

blueblue

Blue Blue
Patrick
Opal | Level 21

Below worked for me once I've run the macro definition as found in this paper AND also fixed the name of the parameter in your code.

 

From:

Patrick_0-1635199792860.png

To:

Patrick_1-1635199837321.png

 

%macro dir_contents(
      dir= /* directory name to process */
      , ext= /* optional extension to filter on */
      , dsout=work.dir_contents /* dataset name to hold the file names */
      , attribs=N /* get file attributes? (Y/N ) */
  );
  %global _dir_fileN;
  %local _syspathdlim _exitmsg _attrib_vars;

  %* verify the required parameter has been provided.;
  %if %length(&dir) = 0 %then
    %do;
      %let _exitmsg = %str(E)RROR: No directory name specified - macro will exit.;
      %goto finish;
    %end;

  %* verify existence of the requested directory name.;
  %if %sysfunc(fileexist(&dir)) = 0 %then
    %do;
      %let _exitmsg = %str(E)RROR: Specified input location, &dir., does not exist - macro
        will exit.;
      %goto finish;
    %end;

  %* set the separator character needed for the full file path:;
  %* (backslash for Windows, forward slash for UNIX systems);
  %if &sysscp = WIN %then
    %do;
      %let _syspathdlim = \;
    %end;
  %else
    %do;
      %let _syspathdlim = /;
    %end;

  /*--- begin data step to capture names of all file names found in the specified
  directory. ---*/
  data &dsout(keep=file_seq basefile pathname);
    length basefile $ 40 pathname $ 1000 _msg $ 1000;

    /* Allocate directory */
    rc=FILENAME('xdir', "&dir");

    if rc ne 0 then
      do;
        _msg = "E" || 'RROR: Unable to assign fileref to specified directory. ' ||
          sysmsg();
        go to finish_datastep;
      end;

    /* Open directory */
    dirid=DOPEN('xdir');

    if dirid eq 0 then
      do;
        _msg = "E" || 'RROR: Unable to open specified directory. ' || sysmsg();
        go to finish_datastep;
      end;

    /* Get number of information items */
    nfiles=DNUM(dirid);

    do j = 1 to nfiles;
      basefile = dread(dirid, j);
      pathname=strip("&dir") || "&_syspathdlim." || strip(basefile);

      %if %length(&ext) %then
        %do;
          /* scan the final "word" of the full file name, delimited by dot character. */
          ext = scan(basefile,-1,'.');

          if ext="&ext." then
            do;
              file_seq + 1;
              output;
            end;
        %end;
      %else
        %do;
          file_seq + 1;
          output;
        %end;
    end;

    /* Close the directory */
    rc=DCLOSE(dirid);

    /* Deallocate the directory */
    rc=FILENAME('xdir');
    call symputx('_dir_fileN', file_seq);
finish_datastep:

    if _msg ne ' ' then
      do;
        call symput('_exitmsg', _msg);
      end;
  run;

  %if %upcase(&attribs)=Y and &_dir_fileN > 0 %then
    %do;

      data _file_attr(keep=file_seq basefile infoname infoval);
        length infoname infoval $ 500;
        set &dsout.;

        /* open each file to get the additional attributes available. */
        rc=filename("afile", pathname);
        fid=fopen("afile");

        /* return the number of system-dependent information items available for the
        external file. */
        infonum=foptnum(fid);

        /* loop to get the name and value of each information item. */
        do i=1 to infonum;
          infoname=foptname(fid,i);
          infoval=finfo(fid,infoname);

          if upcase(infoname) ne 'FILENAME' then
            output;
        end;

        close=fclose(fid);
      run;

      /* transpose each information item into its own variable */
      proc transpose data=_file_attr out=trans_attr(drop=_:);
        by file_seq basefile;
        var infoval;
        id infoname;
      run;

      proc sql noprint;
        select distinct name into : _attrib_vars separated by ', '
          from dictionary.columns
            where memname='TRANS_ATTR' and upcase(name) not in('BASEFILE', 'FILE_SEQ')
              order by varnum;
      quit;

      /* merge back the additional attributes to the related file name. */
      data &dsout.;
        merge &dsout. trans_attr;
        by file_seq basefile;
      run;

      proc datasets nolist memtype=data lib=work;
        delete _file_attr trans_attr;
      run;

      quit;

    %end;

  %if %length(&_exitmsg) = 0 %then
    %let _exitmsg = NOTE: &dsout created with &_dir_fileN. file names;

  %if %length(&ext) %then
    %let _exitmsg = &_exitmsg where extension is equal to &ext.;
  %let _exitmsg = &_exitmsg from &dir..;

%finish:
  %put &_exitmsg;

  %if %length(&_attrib_vars) ne 0 %then
    %do;
      %put;
      %put NOTE: File attributes were requested and have been added to &dsout.. Variable
        names are &_attrib_vars.;
    %end;
%mend dir_contents;


option mautolocdisplay;
%let mypath=c:\temp;

%dir_contents (dir=&mypath., ext=, dsout=theseFiles, attribs=N);
GN0001
Barite | Level 11

Hello team,

I didn't say it doesn't work. I just aske if it accesses to the files in subdirectory.

Regards,

blueblue

Blue Blue
Patrick
Opal | Level 21

@GN0001 wrote:

Hello team,

I didn't say it doesn't work. I just aske if it accesses to the files in subdirectory.

Regards,

blueblue


Why don't you just execute the macro in your environment. That should answer your question. ...or even better try to actually understand the macro code.

GN0001
Barite | Level 11
Hello teammate,
Actually, it lists the files in subdirectory.
It is abstract. From what I see in the output, I can say, it creates an dataset, observations for this dataset is folder names. %dir_contents list the files in each folder name. It displays folder name in output dataset, but it access to content of each folder.

Regards,
blueblue
Blue Blue
GN0001
Barite | Level 11
Hello,
I need to test it though.
Regards,
BlueBlue
Blue Blue

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 22 replies
  • 1958 views
  • 9 likes
  • 6 in conversation