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

I am attempting to collect all of the csv files in a folder using the filename and pipe statements. I can get it to work when I directly specify what the dir is, but wondered if I could have it inserted through a macro.

The code that I think should work is:

1       %macro um;

2       %let source = C:\Users\Home\Folder;

3       %let me = %quote(%'dir %"&source\*.csv%" %');

4       %let rex = %bquote(filename DIRLIST pipe &me.);

5       filename DIRLIST pipe &me.;

6       &rex;

7       data dirlist ;                                              

8       infile dirlist lrecl=200 truncover;                         

9       input line $200.;                                           

10     if input(substr(line,1,10), ?? mmddyy10.) = . then delete;              

11     parse = substr(line,40,50 );

12     file_name = substr(parse,1,length(parse)-4);

13     keep file_name parse;

14     run;

15     %mend;

16     %um;

I highlighted in blue where the lines should be inserted inside of quotation marks. For reference line 5 and 6 should duplicate the same text, which would be

filename dirlist pipe 'dir "C:\Users\Home\Folder\*.csv" ';

But when I run it, it always gives me the error "ERROR: Error in the FILENAME statement.". It seems that the main issue here is the use of unbalanced quotation marks in the macro, otherwise I could simply have it written as filename dirlist pipe 'dir "&source.\*.csv" '; But this statement because I have not specified %quote absorbs the parentheses. Any advice on how to have this run correctly would be appreciated.

Thanks

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

Using SAS Macro to pipe a list of filenames from a Windows directory - Stack Overflow

Here's a whole bunch of different solutions to the same question. Hopefully one works for you Smiley Happy

One other thing, I'm surprised to not see a scan function in your code to get the file name. 

View solution in original post

6 REPLIES 6
ballardw
Super User

You are likely attempting to generate way too many quotes to begin with.

filename dirlist pipe "dir &source.\*.csv"; should work as the DIR command doesn't require the path to be in quotes. However you may want to check this link for possible other issues: http://support.sas.com/kb/41/863.html

overmar
Obsidian | Level 7

If I remove the quotes (' ')from the dir statement I am given this response

ERROR: Error in the FILENAME statement.

ERROR 23-2: Invalid option name dir.

I agree that the cause of the problem is adding two sets of quotation marks, but wondered if anyone had an idea of how to either do this in more steps so the macro wouldn't crash, or another way to have program read the quotation marks correctly. Of note I can get it to insert the correct line into the macro, but then the filename statement doesn't run correctly.

Reeza
Super User

I'm assuming you're trying to get a list of CSV files from a directory, and assuming you're on Windows?

overmar
Obsidian | Level 7

Correct on both accounts

Reeza
Super User

Using SAS Macro to pipe a list of filenames from a Windows directory - Stack Overflow

Here's a whole bunch of different solutions to the same question. Hopefully one works for you Smiley Happy

One other thing, I'm surprised to not see a scan function in your code to get the file name. 

overmar
Obsidian | Level 7

Thanks for the advice, the scan function was written farther down in the macro and I cut it off at reading the file names into table so there wouldn't be unnecessary code. But here is what the code looks like once I implemented your suggestions and it is working now.

%LET source = C:\Users\Home\Documents\;

%LET library = out;

libname &library "&source";

%macro daily(type = );

%macro get_filenames(location);

filename _dir_ "%bquote(&location.)";

data filenames(keep=memname);

  handle=dopen( '_dir_' );

  if handle > 0 then do;

    count=dnum(handle);

    do i=1 to count;

      memname=dread(handle,i);

      output filenames;

    end;

  end;

  rc=dclose(handle);

run;

filename _dir_ clear;

%mend;

%get_filenames(&source);  

data dirlist ;                                              

    set filenames;

    if substr(memname,length(memname)-2,3) ~="&type" then delete;

    parse = substr(memname,1,length(memname)-4);

    file_name = memname;

    keep file_name parse;

run;

proc sql noprint;

select parse, file_name

into :parse_list separated by '*', :file_list separated by '*'

from dirlist;

quit;

%let cntlist = &sqlobs;

%do i = 1 %to &cntlist;

%let parse = %scan(&parse_list.,&I.,"*");

%let file = %scan(&file_list.,&I.,"*");

proc import out=daily_&i

      datafile="&source\&parse"

     dbms=csv replace;

     getnames=yes;

     guessingrows=10000;

run;

%end;

%mend;

%daily(type = txt);

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
  • 6 replies
  • 2246 views
  • 3 likes
  • 3 in conversation