my code to send mail using sas data step. here trying to create a code to send mail.
FILENAME outbox EMAIL ("***********");
DATA _NULL_;
FILE outbox
TO=("************")
FROM=("***********")
SUBJECT=("Example of a SAS E-mail" );
/* ATTACH=(""); */
PUT " ";
PUT "Hello Boss,";
PUT " ";
PUT "Attached are the Daily Operational Reports.";
PUT " ";
PUT "rrt";
RUN;
I don't tend to include email parameters in the datastep itself, but rather in fileref. I have tested the code below with my email address and it worked.
As I said in the comments, you simply need to wrap your datastep in a macro if you want it to run within macro.
You can have positional or keyword parameters. See this source for detailed info. I have used keyword parameters in this example. you call the macro by specifying the keyword and then the value like I showed the last line. If you don't put anything, then the keyword gets ignored.
By the way, the empty keywords result in initialised local macro variables. Let statements like ( %LET FROM=FROM="&FROM") are there to add a string "FROM=" to the beginning of "FROM" macro variable so the filename syntax would be complete. If macro variable such as "FROM" would be passed as is, it would resolve to email address that filename woudn't know what to do with.
%MACRO send_email (TO=,FROM=,SUBJECT=,ATTACHMENT=,BODY=);
%IF &TO ne %THEN
%LET TO="&TO";
%IF &FROM ne %THEN
%LET FROM=FROM="&FROM";
%IF &SUBJECT ne %THEN
%LET SUBJECT=SUBJECT="&SUBJECT";
%IF &ATTACHMENT ne %THEN
%LET ATTACHMENT=ATTACHMENT="&ATTACHMENT";
%IF &BODY ne %THEN
%LET BODY="&BODY";
FILENAME outbox EMAIL &TO &FROM &SUBJECT &ATTACHMENT;
DATA _NULL_;
FILE outbox;
PUT &BODY;
RUN;
%MEND;
%send_email(email=example#example.com);
Peeyush,
Try the code sample below. Make sure to enter your SMTP email host details and the email addresses to and from. You can make the email addresses macro variables if you want additional automation:
%macro emailM;
OPTIONS emailsys = SMTP emailhost = Youremail.Host.net emailport= 25;
FILENAME Mailbox EMAIL 'You#something.com';
attach=("\\somewhere\something\File.xls");
DATA _NULL_;
FILE MailBox TO=("somebody#something.com" "somebody2#something.com")
Subject="Example of a SAS E-mail";
PUT "Hello Boss,";
PUT " ";
PUT "Attached are the Daily Operational Reports.";
PUT " ";
PUT "Thank you";
RUN;
%mend emailM;
%emailM;
Related
I am trying to write a macro wherein my paramter has multiple values and a few of those are prefxed with space. I want to be able to read in the strings along with the space, but space being the default delimiter is causing issues.
`%macro ab(where_p=);
data want;
set have;
%DO I =1 %TO %SYSFUNC(COUNTW(&WHERE_P));
%IF %LENGTH(&WHERE_P) > 0 %THEN %DO;
B_&I=%SCAN(%STR(&WHERE_P),&I);
%end;
%end;
run;
%mend;
%ab(WHERE_P=" ATF" " TRUST");`
Here it is not able to read in values as is, it reads a space as one string then ATF as next and then space again and TRUST as next. Wherein, it should read ' ATF' as one string and 'TRUST'as second.
Can someone help read in such data using scan function.
Thanks
Just use the functionality of the %SCAN() function to handle this. If the data includes the delimiter then the values need to be quoted.
%let WHERE_P=" ATF" " TRUST";
%let word1 = %scan(&where_p,1,%str( ),q);
So your loop should look like:
%IF %LENGTH(&WHERE_P) %THEN %DO I =1 %TO %SYSFUNC(COUNTW(&WHERE_P,%str( ),q));
B_&I=%SCAN(&where_p,&I,%str( ),q);
%end;
...
%ab(WHERE_P=" ATF" " TRUST");`
Or you could use a different delimiter that does NOT appear in the data. If you want to pass in leading spaces without actual quotes then you need to use macro quoting.
%IF %LENGTH(&WHERE_P) %THEN %DO I =1 %TO %SYSFUNC(COUNTW(&WHERE_P,|));
B_&I=%sysfunc(quote(%qSCAN(&where_p,&I,|)));
%end;
...
%ab(WHERE_P=%str( ATF| TRUST));
Try:
%macro ab(where_p=);
%let array_size = %EVAL(%SYSFUNC(COUNTC(&WHERE_P, '"'))/2);
data want;
set have;
array B_(&array_size) $20 (&where_p);
run;
%mend;
%ab(WHERE_P=" ATF" " TRUST" );
You first find the number of items which is number of quotes divided by 2.
Then create an array of that size and assign values using &WHERE_P directly.
If you want to allow strings in WHERE_P longer than 20 chars, you need to change the length in the array line.
I am getting a generic 'Statement not valid or out of order' message with the below:
%macro test;
data _null_;
%if %sysfunc(fileexist("C:\report_201809.xlsx")) = 1 %then %do;
rc=%sysfunc(rename("C:\report_201809.xlsx",
"C:\report_201809.xlsx"_old.xlsx",'file'));
%end;
%mend;
%test;
The code below should get you what you need. While you can use %if statements in a data step you generally won't need to. I'm guessing the error is coming from the %sysfunc function around the fileexist and rename functions. %sysfunc allows you to call data step functions outside of a data step so it is not needed here.
%macro test;
data _null_;
if fileexist("C:\file.txt") then do;
rc = rename("C:\file.txt", "C:\file2.txt", 'file');
end;
run;
%mend;
Alternatively, you could use an X Command that allows you to execute Windows commands. You could replace the rename function with the following statement.
x move C:\file.txt C:\file2.txt;
Remove the DATA _NULL_ or proceed per #J_Lard.
Macro arguments used in %sysfunc invoked function calls are implicitly quoted and do not need additional ' or "
%macro test;
%local rc;
%if %sysfunc(fileexist(C:\report_201809.xlsx)) = 1 %then %do;
%let rc = %sysfunc(rename(C:\report_201809.xlsx,C:\report_201809_old.xlsx,file));
%end;
%test;
You original code may have worked (by way of non-obvious side effect) if the filename "C:\report_201809.xlsx"_old.xlsx" (having an extraneous ") was corrected to "C:\report_201809_old.xlsx"
I have two numeric variables, date1 and date2, which are both currently set to 20170502.
In my macro, I want to send an email if the two variables are equal. This is my code:
%let date1 = input(put(intnx('day', today(),-3),yymmddn8.),8.);
%macro EMAIL;
filename INSRNC email;
data _null_;
%if &date1. = &date2. %then %do;
file INSRNC to="email#address"
subject= "test";
put "email message";
%end;
run;
%mend;
%EMAIL;
I am getting the error message: "Required operator not found in expression"
Am I using the wrong operator?
Thanks
If these are defined macro variables, then this should work as you posted it. I would recommend making a modification; you should pass date1 and date2 as parameters, even if they are just passed as is, due to the principle of encapsulation. But what you posted would work, just based on global macro variables.
%let date1=20140101;
%let date2=20140101;
%macro EMAIL(date1=, date2=);
filename INSRNC email;
data _null_;
%if &date1. = &date2. %then %do;
*file INSRNC to="email#address"
subject= "test";
put "email message";
%end;
run;
%mend;
%EMAIL(date1=&date1., date2=&date2.);
If you're getting required operator not found in expression then your macro variables are not correctly defined and may have a character in them that is making this fail to read properly. Use OPTIONS MPRINT SYMBOLGEN; to see why.
#Joe gave a perfect explanation on how to define macros. Passing the macros as parameters makes it far easy. However, looking at your comment on how date1 is getting resolved, please see the below
date1 = %sysfunc(input(put(intnx('day', today(),-3),yymmddn8.),8.));
Kindly read through the importance of %Sysfunc in resolving macros to have a better understanding.
I using index to avoid duplicates everytime dataset gets updated and send mail according its failure and success. Below is the code.
data lib.new(index =(dual=(name date)/ unique));
set lib.old;
run;
options emailsys=smtp;
%macro sendmail;
%if &syserr ne 0 %then %do;
data _null_;
filename mailbox EMAIL 'abc#gmail.com' subject ='Failed';
file mailbox;
put "Data already avaialable. Please submit for different";
run; %end;
%else %do; data _null_;
filename mailbox EMAIL 'abc#gmail.com' subject ='Success';
file mailbox;
put "Data created"; run; %end;
%mend sendmail;
%sendmail;
when I run above code. I can receive mail whenever data update is success. But when I am not receiving mail when it fails
Is there any other way to do.
For success. I am getting below log with email details and mail triggered.
SYMBOLGEN: Macro variable SYSERR resolves to 0
MACROGEN(SENDMAIL): data _null_;
MACROGEN(SENDMAIL): filename mailbox EMAIL 'abc#gmail.com' subject 'Success';
MACROGEN(SENDMAIL): file mailbox;
MACROGEN(SENDMAIL): put "Data created";
MACROGEN(SENDMAIL): run;
NOTE: The file MAILBOX is:
E-Mail Access Device
Message sent
To: "abc#gmail.com"
The SAS System
Cc:
Bcc:
Subject: Job Success
Attachments:
NOTE: 1 record was written to the file MAILBOX.
For failure. I am getting below log and mail not triggered
SYMBOLGEN: Macro variable SYSERR resolves to 1012
MACROGEN(SENDMAIL): data _null_;
MACROGEN(SENDMAIL): filename mailbox EMAIL 'abc#gmail.com' subject ='Job Failed';
MACROGEN(SENDMAIL): file mailbox;
The SAS System
MACROGEN(SENDMAIL): put "Data already available. Please submit for different";
MACROGEN(SENDMAIL): run;
The filename statement should be before a data step. Try this.
options emailsys=smtp;
%macro sendmail;
filename mailbox EMAIL 'abc#gmail.com';
data _null_;
file mailbox;
%if &syserr ne 0 %then %do;
put '!em_subject! "Failed"';
put "Data already avaialable. Please submit for different";
%end;
%else %do;
put '!em_subject! "Success"';
put "Data created";
%end;
run;
%mend sendmail;
%sendmail
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;