Hello,
I'm trying to solve a bug in my code where I have some if...then...do...else...do logic. The bug is that the code 'does' both tasks regardless of passing/failing condition. Specifically, the code is supposed to do nothing in a 'Success' (mkt_count > 350). In a failure, (mkt count < 350), it should spit out an email. However, an email is being generated in both cases (even though no warnings or errors are thrown). Any idea what I'm doing wrong? I'm using SAS Enterprise Guide 7 if that matters.
data _null_;
%let src_tbl='table a';
%let trg_tbl='table b';
if &mkt_count.>350 then
do;
put 'SUCCESS';
call symput('src_tbl','table a');
call symput('trg_tbl','table b');
end;
else
do;
put 'FAILURE';
call symput('src_tbl','table a');
call symput('trg_tbl','table b');
filename getdone email
from='admin@xyz.com'
to=(
'analyst@xyz.com'
)
subject="(Teradata &code_env) Subject line"
content_type="text/html";
ods listing close;
ods html style=styles.test body=getdone;
TITLE1 'This email is still under testing as it is throwing false alarm.';
ODS HTML CLOSE;
ODS LISTING;
end;
run;
@Rick_SAS provided a great explanation about global statements versus those that are scoped to your DATA step. Here's an example that shows how to conditionally send an e-mail based on the values that you find in your data. This approach uses the %IF-%THEN-%ELSE statements in open code, which has been possible since SAS 9.4 Maint 5 (released in 2017).
/* Pretend we are counting records where RESULT=1 */
proc sql noprint;
select count(result) into: mkt_count
from source.dataset
where result=1;
quit;
/* If beyond a certain threshold, send e-mail */
options nocenter emailhost='yourmailhost.company.com' emailsys=smtp;
%if &mkt_count. > 350 %then
%do;
filename msg email to=(
'analyst@xyz.com'
)
FROM = "admin@xyz.com"
subject="Alert: Count = &mkt_count., exceeds target"
type='text/html'
;
ods msoffice2k (id=email)
file=msg (title="Alert")
style=dove;
ods noproctitle;
/* SAS proc to generate the body of the e-mail */
title "Results distribution";
proc freq data=source.dataset;
table result;
run;
ods msoffice2k (id=email) close;
%end;
/* under threshold, no alert needed */
%else %do;
%PUT NOTE: Count is &mkt_count. -- under threshold;
%end;
SAS has two kinds of statements. GLOBAL statement such as %LET, FILENAME, TITLE, and ODS statements are always executed. Think of them as being "lifted out" of a procedure. The second kind of statements are program control statements (IF-THEN/ELSE, DO, function calls) that are executed within a DATA step.
In your example, the global statements are executed regardless of the logic of the IF/THEN/ELSE conditions. Run this little example to see that the LIBNAME statement executes even though it is in an ELSE block that never executes:
data _NULL_;
if 1 then do;
x=1;
end;
else do;
x=2;
libname foo "C:/test/";
end;
run;
/* display value of libname */
data _null_;
length Lname $ 100;
Lname=pathname('foo','L');
put Lname=;
run;
I've never done this, so someone will have to help you with the details. What I would suggest, however, is to wrap the relevant "send email" statements into a macro, and then call the macro conditionally. For example, if the code to send the email is in the macro
%macro SendEmail();
...
%mend;
then you can process some data and execute the macro only when some condition is true, as follows:
data _null_;
if &mkt_count > 350 then do; /* ??? how does &mkt_count get defined??? */
put 'SUCCESS';
end;
else do;
put 'FAILURE';
call execute("%SendEmail()");
end;
run;
@Rick_SAS provided a great explanation about global statements versus those that are scoped to your DATA step. Here's an example that shows how to conditionally send an e-mail based on the values that you find in your data. This approach uses the %IF-%THEN-%ELSE statements in open code, which has been possible since SAS 9.4 Maint 5 (released in 2017).
/* Pretend we are counting records where RESULT=1 */
proc sql noprint;
select count(result) into: mkt_count
from source.dataset
where result=1;
quit;
/* If beyond a certain threshold, send e-mail */
options nocenter emailhost='yourmailhost.company.com' emailsys=smtp;
%if &mkt_count. > 350 %then
%do;
filename msg email to=(
'analyst@xyz.com'
)
FROM = "admin@xyz.com"
subject="Alert: Count = &mkt_count., exceeds target"
type='text/html'
;
ods msoffice2k (id=email)
file=msg (title="Alert")
style=dove;
ods noproctitle;
/* SAS proc to generate the body of the e-mail */
title "Results distribution";
proc freq data=source.dataset;
table result;
run;
ods msoffice2k (id=email) close;
%end;
/* under threshold, no alert needed */
%else %do;
%PUT NOTE: Count is &mkt_count. -- under threshold;
%end;
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.