Gracefully terminating a SAS program when a particular dataset is created with zero observations

Reply
Occasional Contributor
Posts: 7

Gracefully terminating a SAS program when a particular dataset is created with zero observations

Here's a little macro I wrote today in SAS 9.3 Windows that will detect a zero-observation condition in a SAS dataset and, if encountered, will replace the contents of the Results Viewer with a message and terminate the SAS program gracefully.  Perhaps not elegant, but I hope some of you will find this to be useful.

Best Regards,

David Oesper

Sul Ross State University

Alpine, TX

%macro zeroobs(l,d);

%* end program if zero observations encountered;

%let lib = %upcase(&l);

%let dsn = %upcase(&d);

proc sql noprint;

    select nobs into :nobs separated by " "

    from dictionary.tables

    where libname = &lib and memname = &dsn;

quit;

%if &nobs = 0 %then %do;

    ods html close;

    ods preferences;

    ods html;

    data zeroobs;

       message = 'NO RECORDS RETURNED - ENDING PROGRAM';

    run;

    proc print data=zeroobs noobs;

       title;

    run;

   %abort cancel;

%end;

%mend zeroobs;

%zeroobs('work','courses');

Occasional Contributor
Posts: 7

Re: Gracefully terminating a SAS program when a particular dataset is created with zero observations

Posted in reply to DavidOesper

I'd recommend adding the following %local statement in at the beginning of the macro to avoid clobbering any macro variables with the same names that might be used in your main SAS program:

%local l d lib dsn nobs;

Best,

Dave

Respected Advisor
Posts: 3,799

Re: Gracefully terminating a SAS program when a particular dataset is created with zero observations

Posted in reply to DavidOesper

Do you really need to know how many?  Consider this data step.

18         data _null_;
19            if eof then
20            put 'No obs in data or subset';
21            stop;
22            set sashelp.class end=eof;
23            where age eq 21;
24            run;

No obs in data or subset
Occasional Contributor
Posts: 7

Re: Gracefully terminating a SAS program when a particular dataset is created with zero observations

Posted in reply to data_null__

Clever, data_null_, interesting data _null_ step usage I have not seen before. Smiley Happy

I still prefer my technique because it clears out the Results Viewer and places a message there instead of the SAS log, and the %abort cancel keeps all the rest of the SAS program from running.

Best Regards,

Dave

Respected Advisor
Posts: 3,799

Re: Gracefully terminating a SAS program when a particular dataset is created with zero observations

Posted in reply to DavidOesper

I'm sure you can still do the clearing and aborting as you see fit.  My point is that you don't need to count anything.  This technique adds the ability to test for a zero obs subset created with a where clause, which for me is a more common application.  Once you "get the answer" what you do is up to you.

Occasional Contributor
Posts: 7

Re: Gracefully terminating a SAS program when a particular dataset is created with zero observations

Posted in reply to data_null__

The beauty of using PROC SQL to read the SAS dictionary tables is that the number of observations has already been counted (NOBS) and I am just reading the value that is already on the table.  So either technique will work fine.  One of the things I love about SAS is there are multiple good ways to do just about anything.  Thanks for sharing your insight.

Dave

Respected Advisor
Posts: 3,799

Re: Gracefully terminating a SAS program when a particular dataset is created with zero observations

Posted in reply to DavidOesper

You might consider a different variable from dictionary.tables

nlobs num label='Number of Logical Observations',


As demonstrated by this program using NOBS which produces and incorrect result.  Of course the example is somewhat contrived.

data class;
   set sashelp.class;
   run;
data class;
   modify class;
   remove;
  
run;

proc sql noprint;
  
describe table dictionary.tables;
    select nobs into :nobs separated by " "
   
from dictionary.tables
   
where libname eq 'WORK' and memname eq 'CLASS';
quit;
%put NOTE: nobs=&nobs;
Ask a Question
Discussion stats
  • 6 replies
  • 304 views
  • 0 likes
  • 2 in conversation