Send an email for each row in a SAS data set - macros

I have a data set (work.employees) where each field is an element of an email to be sent out. Example record: Smith, John, John.Smith#Company.com, JohnsManager#Company.com. For each record, I need to send a separate email based on the information there. I can send one email with macro variables, and have piddled around with a data null email, but the iteration isn't happening. Suggestions would be very appreciated. Thanks.

So you want to send email notification through sas? The issue is two folded. First you need to make sure your SMTP server is properly configured in SAS. Secondly you have to make the required mailing software.
For first bit follow the guide in http://support.sas.com/kb/19/767.html
Now what you want (apparently) is to parse/select the emails. I'm going to assume you only select them from data set.
Proc sql;
select distinct(emails) into: resplist separated by ' ' from mail_set where emails like '%#%';
/*Here I'm selecting only those that have # mark in the cells.
You can add parser as you need. (question is a bit oddly worded.*/
quit;
Alternatively, you can hardCode the addresses. (I suggest you try 1st with this so you know your sending code works.
%let respList="Frist.last#email.com" "Second.Recipiant#email.com";
FILENAME Mailbox EMAIL &respList.
Subject="Email delivery for you";
DATA _NULL_;
FILE Mailbox;
PUT "Good day,";
put ;
PUT "Remain calm. This is a test.";
PUT ;
run;
You can also add sas datasets informatin, but bear in mind that spamming stuff through email is usually bad idea.

If you want to send one email per record, it's better to use the !EM_ directives in your datastep.
http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a002058232.htm
filename reports email "Jim.Smith#work.com";
data _null_;
file reports;
length name dept $ 21;
input name dept;
put '!EM_TO! ' name;
put '!EM_SUBJECT! Report for ' dept;
put name ',';
put 'Here is the latest report for ' dept '.' ;
if dept='marketing' then
put '!EM_ATTACH! c:\mktrept.txt';
else /* ATTACH the appropriate report */
put '!EM_ATTACH! c:\devrept.txt';
put '!EM_SEND!';
put '!EM_NEWMSG!';
put '!EM_ABORT!';
datalines;
Susan marketing
Peter marketing
Alma development
Andre development
;
run;

Related

SAS automail not working

I am new at SAS and I have this SAS macro, it will send me a email when the process has finished, but it is not working properly.
In the log just say macros's name like it work but the email is not coming to my inbox.
%macro mailing()
data _null_;
start = %eval(%sysfunc(today(), mmddyy5)-1);
endd = %eval(%sysfunc(today(), mmddyy5)-8);
run;
FILENAME mail EMAIL
SUBJECT=" corporative subject"
FROM='corporativemail#server.com'
SENDER='corporativemail#server.com'
TO=("mymail#server.com")
DATA _NULL_;
FILE mail;
PUT "Hi,";
PUT "here goes &start. - $endd. ";
PUT "Best Regards,";
PUT "me";
RUN;
%mend
%macro mailing()
By the way, I do not know if those date variables are properly defined
The issue is that you are not actually calling the macro. You only use %macro when defining a macro.
To call it, simply precede the macro name with a % symbol, as follows:
%mailing()

How to remove the extra space as a result of double quotes in SAS

I am new to SAS and I am trying create a batch file through a SAS program. The code is below:
data new;
enddate=date();
getdate=date()+1;
flname1=compress("d:\temp\file"||year(enddate)||put(month(enddate),z2.)||
put(day(enddate),z2.)||".txt");
begdate=enddate-&days;
dtline1=compbl(compress("00:00_"||put(begdate,mmddyy10.))||" "||
compress("00:00_"||put(getdate,mmddyy10.)));
file 'h:\programs\daily_file';
put 'LOGIN abc xyz';
put 'FILE(C:\temp\list.txt)
dtline1 "script.pl("flname1")";
put 'LOGOUT';
Script.pl is a perl script and in the resulting batch file, there is an extra space after flname1. It prints something like this:
script.pl(d:\temp\file_date ).
I don't want the this extra space after date. What can I do?
The easiest way to get that to work properly is simply to put the entire command (script.pl(filename)) into a single variable, then put that variable.
You can also use +(-1) in put to move the line pointer back one, if it's consistently off by one (though most of the time that's not needed).
put "script.pl(" flname1 +(-1) ")";
It really looks like you are working too hard to create string variables before writing to the file. You should be able to write what you want just using the features of the PUT statement. It is not clear from the question what format you want the file to have, but I think this code mimics your program.
%let days=7 ;
data new;
enddate=date();
getdate=date()+1;
begdate=enddate-&days;
file 'h:\programs\daily_file';
put 'LOGIN abc xyz'
/ 'FILE(C:\temp\list.txt) 00:00_' begdate mmddyy10.
' 00:00_' getdate mmddyy10.
' script.pl(d:\temp\file' enddate yymmddn8. '.txt)'
/ 'LOGOUT'
;
run;
and it produces:
LOGIN abc xyz
FILE(C:\temp\list.txt) 00:00_08/14/2015 00:00_08/22/2015 script.pl(d:\temp\file20150821.txt)
LOGOUT

Print fields being browsed on the screen

I need to write a FM script which print one field of the records being browsed on the screen and separated by commas.However, I do not know how to select the records being currently browsed and am not able to find it in the documentation (the lack of the good keyword could be the problem).
Thank you!
It sounds like you're trying to create a list of all values for one field in the Found Set. FileMaker 13 introduced the List of Summary type, which makes this pretty easy:
First, create a Summary field, say FoundAddresses. Make it a List of your e-mail address field. This field will contain a return-delimited list of the e-mail addresses in the Found Set.
Second, create a Calculation field, say FoundAddressesCommaDelimited. Make it the following text Calculation:
Substitute (
GetSummary ( FoundAddresses ; FoundAddresses ) ;
ΒΆ ; ", "
)
This will substitute all of the returns in FoundAddresses for comma-space.

Using data step to append custom text to ODS stream

I'm trying to print out a table to an email destination and then put some custom comments at the end. When I try and run the below code I get the message:
ERROR: File is in use, .
My code is:
filename mymail email content_type="text/html"
to=("myemail#myemail.com")
from=("myemail#myemail.com")
subject="My Report";
ods html3 body=mymail style=sasweb;
proc print data=sashelp.class noobs;
run;
data _null_;
file mymail ;
put "I want this to appear at the bottom of the email.";
run;
ods html3 close;
filename mymail clear;
I've tried googling for help but the search terms are so vague it's tough to narrow it down to this specific problem. Thanks for the help.
EDIT: Just to clarify - I want all the results in the body of the email. I don't want the results sent as an attachment. Also, if you comment out just the data step in the above code, the email works fine.
I wasn't able to test these two approaches in an actual email, but they did avoid the (replicable) Error: File is in use message..
filename mymail "C:/temp/test.html";
ods html3 body=mymail style=sasweb;
proc print data=sashelp.class noobs;
footnote "Approach 1: I want this to appear at the bottom of the email.";
run;
data _null_;
file print ;
put "Approach 2: I also want this to appear at the bottom of the email.";
run;
ods html3 close;
filename mymail clear;
The change is to use the file print reference in the data step. According to the SAS Documentation:
PRINT is a reserved fileref that directs the output that is produced by any PUT statements to the same file as the output that is produced by SAS procedures.
Its not clear to me whether you actually needed the data step to do any data processing, versus just printing text. I recently had a similar challenge, but my focus was on simply printing text, so you can use the ODS text function:
ODS HTML3 text="Approach 3: Use the ODS TEXT function to put text anywhere.";
Depending upon your html destination, you can use css or html tags to govern font, size, alignment, etc. I'll guess you're using html3 for outlook compatibility, so css tags won't work.

Maildrop: Filter mail by Date: header

I'm using getmail + maildrop + mutt + msmtp chain with messages stored in Maildir. Very big inbox bothers me, so i wanted to organize mail by date like that:
Maildir
|-2010.11->all messages with "Date: *, * Nov 2010 *"
|-2010.12->same as above...
|-2011.01
`-2011.02
I've googled much and read about mailfilter language, but still it is hard for me to write such filter. Maildrop's mailing list archives has almost nothing on this (as far as i scanned through it). There is some semi-solution on https://unix.stackexchange.com/questions/3092/organize-email-by-date-using-procmail-or-maildrop, but i don't like it, because i want to use "Date:" header and i want to sort by month like "YEAR.MONTH" in digits.
Any help, thoughts, links, materials will be appreciated.
Using mostly man pages, I came up with the following solution for use on Ubuntu 10.04. Create a mailfilter file called, for example, mailfilter-archive with the following content:
DEFAULT="$HOME/mail-archive"
MAILDIR="$DEFAULT"
# Uncomment the following to get logging output
#logfile $HOME/tmp/maildrop-archive.log
# Create maildir folder if it does not exist
`[ -d $DEFAULT ] || maildirmake $DEFAULT`
if (/^date:\s+(.+)$/)
{
datefile=`date -d "$MATCH1" +%Y-%m`
to $DEFAULT/$datefile
}
# In case the message is missing a date header, send it to a default mail file
to $DEFAULT/inbox
This uses the date command, taking the date header content as input (assuming it is in RFC-2822 format) and producing a formatted date to use as the mail file name.
Then execute the following on existing mail files to archive your messages:
cat mail1 mail2 mail3 mail4 | reformail -s maildrop mailfilter-archive
If the mail-archive contents look good, you could remove the mail1, mail2, mail3, mail4, etc. mail files.