BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
ursamajor
Calcite | Level 5

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;

 

1 ACCEPTED SOLUTION

Accepted Solutions
ChrisHemedinger
Community Manager

@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;

 

It's time to register for SAS Innovate! Join your SAS user peers in Las Vegas on April 16-19 2024.

View solution in original post

4 REPLIES 4
Rick_SAS
SAS Super FREQ

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;
ursamajor
Calcite | Level 5
Thank you @Rick_SAS for that explanation. It certainly makes sense now. But what do you suggest would be a workaround? Is there any way to make sure that ELSE only executes when the IF condition is not met?
Rick_SAS
SAS Super FREQ

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;

 

ChrisHemedinger
Community Manager

@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;

 

It's time to register for SAS Innovate! Join your SAS user peers in Las Vegas on April 16-19 2024.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 4 replies
  • 34498 views
  • 0 likes
  • 3 in conversation