Is there a way to stop my SAS program from keep executing after facing an error?
To illustrate, I write down three lines of code. The first line works fine, but the second line doesn't work due to an error. The last line is the part where I don't want SAS to execute. In other words, I want SAS to stop working after the second line (when facing the error) so that I can fix my code.
As you all know, SAS executes every line of code regardless of whether it faces an error or not.
data test; set sashelp.cars; run;
proc sort data= test; by typ; run;
*this code yields an error message because typ doesn't exist;
*this is where I want my SAS to stop;
data test2; set test; run;
*so, I want SAS not to execute this line of code if SAS faces an error earlier;
@braam: Here is one way to accomplish what you want, but it has its own inherent problem, namely that the only way I know of to turn the macro off is to restart your SAS session.
It will work if all of the steps in your code end with a 'run;' statement and the string 'run' only occurs in those instances (e.g., you don't try create, say, a file call FirstRun). The approach creates an old style macro called run. Each time the the string run is found the macro substitues the string with the %Rnquit macro (I had to change the name so the macro didn't use 'run' as part of its name.
Normally, one can turn off the macro by using the %deact statement (e.g., %deact Run; ). However, that brings up the conflict because the string Run will be substituted with the Run macro. Possibly someone else can figure out a way to deactivate the macro short of restarting the SAS session.
I also expect to get some flak for suggesting the use of an old style macro as they're no longer documented.
%Macro Rnquit;
; run; quit;
%if %eval(&syserr > 0) %then %do ;
%abort cancel;
%end;
%Mend Rnquit;
macro Run;
%%Rnquit
%
data test; set sashelp.cars; run;
proc sort data= test; by type; run;
proc sort data= test; by typ; run;
data test2; set test; run;
Art, CEO, AnalystFinder.com
There is!
data test; set sashelp.cars; run;
proc sort data= test; by typ; run;
*this code yields an error message because typ doesn't exist;
*this is where I want my SAS to stop;
%macro OnlyRunWithoutError;
%if &syserr = 0 %then %do;
data test2; set test; run;
*so, I want SAS not to execute this line of code if SAS faces an error earlier;
%end;
%mend OnlyRunWithoutError;
%OnlyRunWithoutError;
You could always create and run a macro after each step. e.g.:
%Macro Runquit; /* create a macro to use at end of data and proc steps. */
; run; quit;
%if %eval(&syserr > 0) %then %do ;
%abort cancel;
%end;
%Mend Runquit ; /* if error is encountered, this macro will stop running the entire program but won't close the session */
dat test; set sashelp.cars; run;
%Runquit
proc sort data= test; by typ; run;
%Runquit
data test2; set test; run;
%Runquit
Art, CEO, AnalystFinder.com
Thanks for your replies! But do I have to have such a statement for every step? Would there be a way to declare such a statement just once when I run a batch of statements?
You would include it every time you want to check if there was an error and abort if there is. You don't have to include it if you want to continue anyway.
Running your SAS program in batch mode with the ERRORABEND option is a simple way to do what you want.
Thanks! That looks like what I was looking for. But one issue is that having that option actually "terminates" my SAS when facing an error message, so I have to execute SAS again. Rather, I would like to have a chance to look at my code to fix this issue when facing an error message.
As you guided, I ran the below code.
options ERRORABEND;
data test; set sashelp.cars; run;
proc sort data= test; by typ; run;
*this code yields an error message because typ doesn't exist;
*this is where I want my SAS to stop;
data test2; set test; run;
*so, I want SAS not to execute this line of code if SAS faces an error earlier;
I faced an error with PROC SORT statement, and SAS started to terminate the program.
Then I got the below SAS Message Log.
Would it be possible for me to stay with my SAS program and to fix my code in such a situation?
That is exactly what ERRORABEND does - it is best for batch processing where a SAS log is written to a file. Another option you could try to stay in the program is SYNTAXCHECK. That will switch SAS into syntax check mode when there is an error - it won't process any more data.
Thanks, so I tried SYNTAXCHECK, but I didn't see any effect of having this code.
As below, I didn't expect the last sentence to be executed, but SAS executed the sentence. Did I do this wrongly?
options SYNTAXCHECK;
proc means data= sashelp.cars; run;
proc univariate data= sashelp.ca; run; /*statement with error*/
proc print data= sashelp.cars (obs=10); run;/*statement without error. But I don't want this sentence to be executed*/
@SASKiwi Sorry that I think I misunderstood the meaning of "batch". I do run my SAS codes interactively using SAS windows, not as a batch job. So, what I want to is to see where my error occurs and fix the issue immediately.
@braam - Syntaxcheck mode means processing still continues but with OBS = 0, so no data is processed. Not quite what you wanted but thought it might be useful.
@braam: Here is one way to accomplish what you want, but it has its own inherent problem, namely that the only way I know of to turn the macro off is to restart your SAS session.
It will work if all of the steps in your code end with a 'run;' statement and the string 'run' only occurs in those instances (e.g., you don't try create, say, a file call FirstRun). The approach creates an old style macro called run. Each time the the string run is found the macro substitues the string with the %Rnquit macro (I had to change the name so the macro didn't use 'run' as part of its name.
Normally, one can turn off the macro by using the %deact statement (e.g., %deact Run; ). However, that brings up the conflict because the string Run will be substituted with the Run macro. Possibly someone else can figure out a way to deactivate the macro short of restarting the SAS session.
I also expect to get some flak for suggesting the use of an old style macro as they're no longer documented.
%Macro Rnquit;
; run; quit;
%if %eval(&syserr > 0) %then %do ;
%abort cancel;
%end;
%Mend Rnquit;
macro Run;
%%Rnquit
%
data test; set sashelp.cars; run;
proc sort data= test; by type; run;
proc sort data= test; by typ; run;
data test2; set test; run;
Art, CEO, AnalystFinder.com
Really appreciate your help! That was actually what I was looking for!
To understand your suggestion better, I did some exercise for myself and found that the issue that you mentioned wouldn't bring any significant issues.
I ran the below three codes, separately (NOT all at once). The first code works well even it includes "run2". The second and third codes don't work because they include "run" either as set name or variable name. So what I have to keep in mind must be NOT using "RUN" as any object, but I can use anything containing "run" in the middle (e.g., running as a variable or set). Hope that I understand it correctly.
By the way, I was quite surprised that SAS doesn't have such a function for users. I believe that it's a "must-have" for programs like SAS.
* code 1 => No Error;
data run2; set sashelp.cars;
run2= type;
run;
* code 2 => Error;
data run; set sashelp.cars;
run2= type;
run;
* code 3 => Error;
data run2; set sashelp.cars;
run= type;
run;
@braam: Been awhile since I've played around with old style macros and, indeed, you were correct in your observations. They appear to only act on the presence of complete strings .. not substrings.
I also re-discovered how to get them to stop functioning .. use the %deact macro call (e.g.,
%deact run;
Art, CEO, AnalystFinder.com
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.