BookmarkSubscribeRSS Feed
SASMom2
Fluorite | Level 6

I have below macro in my SAS code. I have total of 2,000 customers that I run a report for. I have assigned them values from 1,000 to 3,000. When I run the code, at the end, it creates a table called ‘file_&i_allyrs’. I do not get data for same number of customers every time I run it. Sometimes, I get this table for only 1,000 customers and sometimes for 1,800 customers. The ‘i’ below is customer number assigned between 1000 and 3000.

 

%macro Read_ALL;

%do i = &beg %to &end;

 

data cont_&i;

set file_&i_allyrs;

cust = “&i”;

run;

 

/* appending rest of the file_&i._allyrs tables */

 

proc append base = all_files_allyears

           data = cont_&i force;

run;

       %end;

%mend ;

%macro byyr(beg, end);      

       %Read_ALL;

%mend;

%byyr(1000, 3000);

 

So, first it reads 'file_1000_allyrs' table. If this file does not exist, it gives an error and goes to read 'file_1001_allyrs' table..and so on.

Every time the file does not exist, it gives an error. Below is part of the error it gives.

 

ERROR: File FILES_1000_ALLYRS.DATA does not exist.

 

I would like the macro to skip the file it does not exist OR I would like to stop getting an error if the file does not exist.

 

How do accomplish that?

 

Thank you in advance

3 REPLIES 3
Patrick
Opal | Level 21

If the numbering of the files would be at the end then you could reference the files simply by using the colon modifier like:

set file_allyrs_:;

 

Assuming that there could be a table starting with name FILE_... which you don't want included, things become slightly harder. 

data file_1000_allyrs file_1555_allyrs file_2987_allyrs file_2987_notallyrs;
  set sashelp.class;
run;

proc sql noprint;
  select catx('.',libname,memname) into :tbl1-:tbl9999
  from dictionary.tables
  where libname='WORK' and memtype='DATA'
    and prxmatch('/^file_\d{4}_allyrs$/oi',strip(memname))>0
  ;
quit;
%macro tables();
  %do i=1 %to &sqlobs;
    &&tbl&i
  %end;
%mend;

data all_files_allyears;
  length _curr_file $32. cust $4;
  retain cust;
  set %tables() indsname=_curr_file;
  if lag(_curr_file) ne _curr_file then 
    cust = compress(_curr_file,,'kd');
run;

 

....and I can't help myself to also write: You probably should revisit your upstream processing so that you don't end up with multiple tables in first place. Given the power of SAS By-Group processing there is almost never a good reason to split up tables the way it's done here. 

 

Using your code here how this could work:


%macro Read_ALL;
  %do i = &beg %to &end;
    %if %sysfunc(exist(file_&i._allyrs,data)) %then
      %do;
        data cont_&i;
          set file_&i._allyrs;
          cust = "&i";
        run;

        /* appending rest of the file_&i._allyrs tables */
        proc append base = all_files_allyears
          data = cont_&i force;
        run;
      %end;
  %end;
%mend;

%macro byyr(beg, end);
  %Read_ALL;
%mend;

%byyr(1000, 3000);

 

SASMom2
Fluorite | Level 6

Thank you for your quick reply. That worked!

Ksharp
Super User

Add function EXIST() to judge if it existed.

 

%macro Read_ALL;

%do i = &beg %to &end;

%if %sysfunc(exist(file_&i_allyrs)) %then %do;
data cont_&i;
set file_&i_allyrs;
cust = “&i”;
run;
proc append base = all_files_allyears
           data = cont_&i force;
run;
%end;

       %end;

%mend ;

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!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 3 replies
  • 329 views
  • 0 likes
  • 3 in conversation