4

I have several .csv files in a folder that I would like to import into SAS. However, they are not always populated with data, so when I attempt to import an empty file into SAS, I get an error. I am wondering if there is some way for me to check whether or not an external file is empty, and if it is not, bring it into SAS. This is a code that I would like to automate and not have to manually check and account for blank files every time.

I came across this macro in SAS's knowledge base but am unsure of how to modify it so that it would import a .csv file, if I should be using it at all: http://support.sas.com/kb/25/072.html

I appreciate your help.

Joe
  • 62,789
  • 6
  • 49
  • 67
user3023153
  • 47
  • 1
  • 5

1 Answers1

6

This is the macro in question from the link:

%macro test(outf);
 %let filrf=myfile;
 %if %sysfunc(fileexist(&outf)) %then %do;
 %let rc=%sysfunc(filename(filrf,&outf));
 %let fid=%sysfunc(fopen(&filrf));
  %if &fid > 0 %then %do;
   %let rc=%sysfunc(fread(&fid));
   %let rc=%sysfunc(fget(&fid,mystring));
    %if &rc = 0 %then %put &mystring;
    %else %put file is empty;
   %let rc=%sysfunc(fclose(&fid));
  %end;
%let rc=%sysfunc(filename(filrf));
%end;
%else %put file does not exist;
%mend test;

%test(c:\test.txt)

What you'd want to do is change what the macro does in the case that the file is empty. In this case, the fget will return a 0 to the return code (%let rc = ... fget) if it is able to get a string, or it will fail and return a nonzero code.

So, just modify the %if / %else. Instead of putting something, you just do something like

%if &rc=0 %then %do;
  %import_csv(&outf.);
%end;
%else %do;
  %put File &outf. is empty.;
%end;

That assumes you have a macro that does your import. You could, of course, include the full PROC IMPORT code there instead.

This really makes a reasonable error checking wrapper to an import macro, in fact.

%macro import_csv(outf=,outds=);
 %let filrf=myfile;
 %if %sysfunc(fileexist(&outf)) %then %do;
 %let rc=%sysfunc(filename(filrf,&outf));
 %let fid=%sysfunc(fopen(&filrf));
  %if &fid > 0 %then %do;
   %let rc=%sysfunc(fread(&fid));
   %let rc=%sysfunc(fget(&fid,mystring));
   %let rc_close=%sysfunc(fclose(&fid));
    %if &rc = 0 %then %do;
       proc import file="&outf." out="&outds."
                   dbms=csv replace;
       run;
    %end;
    %else %put File &outf. is empty and not imported.;
  %end;
 %let rc=%sysfunc(filename(filrf));
 %end;
 %else %put file does not exist;
%mend test;
Joe
  • 62,789
  • 6
  • 49
  • 67
  • Thanks, Joe! This is perfect! – user3023153 Sep 12 '14 at 16:32
  • what is the %let filerf=myfile statment? – subhro Jan 21 '18 at 05:50
  • @subhro That just defines what you want the temporary fileref to be named (i.e., if you wrote this not with a macro you'd have `filename myfile "c:\temp\test.txt";` or something similar). `myfile` can be whatever you wish to use, and doesn't really matter as long as it doesn't conflict with an already used fileref. – Joe Jan 22 '18 at 15:40