I wrote some code which has to send one letter to one person with specified attachment. Here is the code:
%macro send;
%do i=1 %to &numPeople;
%let name = &&name&i;
%let to = &&UserMail&i;
options emailsys=smtp emailhost=smtp.mail.com emailport=25;
filename outbox email
to=('<Bob#mail.com>' )
type='text/html'
subject="Data for &date_today &to "
from= ('< Dataanalist#mail.com >')
sender=('< Dataanalist#mail.com >')
importance='high'
attach=("/folder/statement&i..xlsx" ct='application/excel');
ods html body=outbox style=seaside;
data _null_;
file outbox;
PUT '<html><body>';
PUT ‘Dear coleagse <br><br>';
ods html close;
run;
%end;
%mend; %send;
The problem is that now this code sends one letter just attachment (without text), the second one to the same person as I need text + attachment. How to avoid first incorrect letter?
There are two statements in your code instructing the email to 'send':
Since you set the destination of the ODS body to 'outbox', the ods html close statement will send the email.
The end of the data step (run;) will send the email.
If you remove both ODS statements (as you don't seem to be using the ODS for anything else), you should get just one email with the attachment and the text.
There's a good SAS Global Forum paper about sending emails from SAS here (PDF):
Paper 038-2008 - Sending E-mail from the DATA step - Erik W. Tilanus, consultant, Driebergen, the Netherlands
Related
I've created a report in SAS EG 7.2 and have got SAS to email it in the body of the email, however I can't seem to add any text. I have got this code:
filename mymail email
to=('mail#email.com')
subject='Report'
from='mail#email.com'
Content_type="text/html";
ods _all_ close;
ODS ESCAPECHAR='^';
ods html body=mymail style=minimal;
proc report data=data…
…
run;
ods html close;
ods _all_ close;
This sends my email perfectly. And I can do this to add some text
filename mymail email
to=('mail#email.com')
subject='Report'
from='mail#email.com'
Content_type="text/html";
ods _all_ close;
ODS ESCAPECHAR='^';
ods html body=mymail style=minimal;
DATA _null_;
file mymail;
Put "Hello,"//
"You are recieving this mail because:"//;
if &warn1=1 then do;
put "&w1." //; end;
if &warn2=1 then do;
put "&w2." //; end;
put
"Regards,"//
"Chris";
run;
ods html close;
ods _all_ close;
But I can't seem to do both? If I include the text step and the proc report, I only see the report in the resulting email. Any ideas?
Thanks in advance :)
If anyone is interested I managed to solve this by adding in the following line directly before the proc report:
ods html text="<div>Please find below the Reports </div> <br><br> There are &&totalwarnings. warnings for the last hour:<br><br>";
%if &warn1=1 %then %do;
ods html text="&&w1."; %end;
%if &warn2=1 %then %do;
ods html text="&&w2."; %end;
Your solution of adding the text into the HTML file itself sounds best.
Your original code has a couple of issue.
First you have an access conflict. The DATA _NULL_ step is trying to write to the same file that the ODS HTML process is still writing to. Didn't you get an error message? or perhaps two separate emails?
Second even if you succeeded in writing text into the same file as the ODS HTML was producing it would be either before or after the <HTML>..</HTML> tags around the report generated by ODS HTML. As such it would probably be ignored by the recipient.
Although I have the error handling:
filename myfile email
to=&e_mail.
subject= "Error: &number."
type="text/plain";
%macro errmail;
%if &syserr ne 0 %then %do;
options obs= max replace nosyntaxcheck;
data _null_;
file myfile;
put;
put 'ERROR';
put "&syserrortext";
put 'check a log'
run;
%abort cancel;
%end;
%mend errmail;
when I have the error in the proc export:
(&number. is the table in the work)
proc export data=&number.
outfile="/usr/local/backup/&number./&number._%SYSFUNC(TODAY(),DATE9.).txt"
replace
dbms=dlm;
delimiter=';';
run;
%errmail;
ERROR: Physical file does not exist, /usr/local/backup/2116/2116_13MAY2016.txt.
NOTE: The SAS System stopped processing this step because of errors.
NOTE: There were 1 observations read from the data set WORK.2116.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
SAS dosen't check a macro and doesn't send an e-mail. I have an error in the path, so I understand the error, but I need an e-mail about that and I want that SAS stops processing because of macro.
Adding some options to the macro can fix it?
this is how I send out my email from SAS
not required to create a file on the system
filename outbox email "email#address.com";
data _null_;
file outbox
to=("email#address.com")
cc=("email#address.com")
subject="SUBJECT OF EMAIL "
/* attach=("C:\sas\results.out" "C:\sas\code.sas") */ ; /* incase you need to attach a file */
put 'Hello! ';
put ' ';
put 'Thank you & let me know if there is anything,';
put "¯ovar."; /*in case you need to put some detail in the email from macro variables make sure to use double quote for that */
put 'SIGNATURE ME';
run;
With the below code the email always gets sent. 1 obviously does not equal 0, but yet it still runs. I have tried removing the do part but still get the same issue.
data _null_;
set TestTable;
if 1 = 0 then do;
file sendit email
to=("email#gmail.com")
subject="Some Subject Line";
end;
run;
While the file statement is considered an executable statement (and thus should not be executed when behind a false if statement), that is not really entirely true. SAS sees the file statement during compilation, and knows that it needs to create a file to write to - and thus, it's somewhat compile-time. That's what is happening here - SAS creates the file (in this case, the email) as a result of the compiler's activity, then doesn't actually populate it with anything, but still has an email at the end of the day.
The same thing happens with any other file - like so:
data _null_;
set sashelp.class;
if 0 then do;
file "c:\temp\test_non_zero.txt";
put name $;
end;
run;
A blank file is created by that code.
If you need to conditionally send emails, I would recommend wrapping your email code in a macro, and then calling that macro using call execute or similar from the dataset. Like so:
%macro write_email(parameters);
data _null_;
file sendit email
to=("email#gmail.com")
subject="Some Subject Line";
run;
%mend write_email;
data _null_;
set TestTable;
if 0 then do;
call execute('%write_email(parameters)');
end;
run;
Use email directives to abort the message.
http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a002058232.htm
data _null_;
file sendit email to=("email#gmail.com") subject="Some Subject Line";
if nobs=0 then put '!EM_ABORT!';
set TestTable nobs=nobs;
....
run;
This is the original code.
filename outmail email type='text/html'
subject='see this'
from="..."
to="..."
attach=("\...\a.pdf"content_type="application/pdf");
ods _all_ close;
ods listing close;
ods html body=outmail style=minimal;
title1 'AAA';
title2 'BBB';
proc tabulate data=
...
run;
ods html close;
ods listing;
But now I don't want to show a tabulated output in the email body, so I remove this part from the original code.
proc tabulate data=
...
run;
The problem is I won't have titles in the email any more. It seems I have to put some proc in the code to make titles exist in the email. But I don't want to show anything in the email body except
Hi all,
Regards,
Balala
Update
I tried this but no luck.
filename outmail email type='text'
subject="AAAA"
from="..."
to="..."
attach=("\\...\text.pdf" content_type="application/pdf");
data _null_;
file outmail;
put 'Hi all,';
put 'First line';
put 'Second line ';
put ' ';
put 'Regards,';
put 'Balala';
run;
But in the email, it shows Hi all,First lineSecond line Regards,Balala.
Update2
The 2nd option doesn't work for me.
1st option doesn't work at first, but when I restart SAS session, it works. But I haven't changed any setting.
And interestingly, I change the type to text/plain instead of text or text/html then everything works fine
You have two options there.
Options 1: HTML tags
Specify HTML tags in your email if you are doing content_type="text/html"
Example:
filename mailbox email 'me#example.com' subject='test email' content_type="text/html";
data _null_;
file mailbox;
put "<body>";
put "<p>Hello,</p>" ;
put "<p>Test email sent <br> Regards,</p>" /
'Automated SAS Code';
put "</body>";
RUN;
Options 2 "Backslash" pointer:
Specify backslash at the end of the line to make the pointer to go over the line. Beware of what Quentin pointed in the comments, you could end up with double lines. Depends on the your SAS platform and email server. Documented here (search for in the document "/"): http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000161869.htm
filename mailbox email 'me#example.com' subject='test email';
data _null_;
file mailbox;
put "Hello," /;
put "Test email sent. "/;
put "Regards," /;
put "Automated SAS Code";
RUN;
Regards,
Vasilij
Is there a way to open a SAS dataset for viewing (i.e., in the "ViewTable" window) from within a .sas file?
I think this will do what you want:
dm log "vt sashelp.air";
Just change the "sashelp.air" part to your lib.table combo.
dw.mackie's answer is right on the money. That works great when submitted from the SAS editor window.
But I just want to caution you to be careful if you attempt it in batch mode (that is, having SAS run a .sas program directly from command-line using the -sysin option). It will indeed attempt to pop open the interactive SAS window environment upon execution.
But, if your batch code also attempts to build some graphs/charts, you'll be required to use the -noterminal option. And the -noterminal option isn't compatible with the dm command. You'd spot it right away in the log, but I just wanted to give you a heads-up.
Because of the size of some of my datasets I just do a simple proc print and limit the output to only 50 observations. I do this so often that I created the following macro that dumps the output to a html file.
%Macro DPrt(Dset, obs=50, vars=, w=, Path="C:\output\");
%LET BKPATH = &Path;
%PUT BKPATH= &BKPATH;
options obs = &obs.;
title;
ods listing close;
ods html
path = &BKPATH.
body = "Debug-&Dset..htm"
style = THEME;
proc print data = &Dset n u split=' ';
%if &vars NE %THEN %DO;
var &vars.;
%END;
%if &w NE %THEN %DO;
&w;
%END;
Run;
ods html close;
ods listing;
options obs = MAX;
%Mend Dprt;
Sample call for dataset test looks like
%dprt(test)