Hello,
I have the following final table (every day the table contents change):
CARD Table:
The code:
%macro mymail(
from=freetalk@gmail.com,
to=,
acct_no=,
branch_id=,
card=,
id=
);
filename outbox email "freetalk@gmail.com" encoding="utf-8";
data _null_;
file outbox
to=( "&to")
from= ("&from")
subject= "Closing &acct_no - &branch_id";
put "Cancel any instructions in the account &acct_no - &branch_id :" ;
put /;
put " &card - &id";
put /;
run;
%mend;
data _null_;
set CARD;
length cmd $500;
cmd=cats( '%mymail(to=',Mail_to,',acct_no=',Account_Number,',branch_id=',Branch_ID,',card=',Card_No,',id=',ID,')' );
call execute(cmd);
run;
Sorry for the pictures, but the post will be deleted if not automatically.
I would appreciate your help.
Hi @shlomiohana - thanks for the code.
It is not necessary to use a macro for this. It can all be done in one data step using first. and last. with by-variables to control the beginning of a new mail and sending it before the next mail starts. Remember to enable the File statement in the code when you try it.
I wrote a "real" program also with the usual bells and whistles, it is included as attachment . And I may have sent test mails to your receivers, I am not sure, so I hope they are fictive mail accounts.
data card;
infile datalines truncover dlm='|' dsd;
input Branch_ID :20. Account_Number :20. ID :20. Card_No :$20. Mail_to :$20.;
datalines;
1|1234567|21312|1231243423|abc@gmail.com
1|1234567|21312|2341245543|abc@gmail.com
12|2342344|23466|8979879879|rer@gmail.com
34|2344523|98986|3453263223|sdr@gmail.com
22|1235534|23214|2353662623|wwt@gmail.com
;
run;
* Sort to make sure first. and last. will work as expected in data step;
proc sort data=&_INPUT;
by Branch_ID Account_Number ID Mail_to Card_No;
run;
* Send emails;
%let mail_from = freetalk@gmail.com;
filename outbox email encoding="utf-8";
data _null;
set card (obs=3);
by Branch_ID Account_Number ID Mail_to;
*file outbox;
if first.Mail_to then do;
account = catx(' ', Account_Number, '- 1');
put '!em_subject! Closing ' account;
put "!em_from! &mail_from";
put '!em_to! ' mail_to;
put 'Cancel any instructions in account ' Account_Number / ;
end;
put card_no '-' ID;
if last.Mail_to then do;
put '!em_send!';
put '!em_newmsg!';
put '!em_abort!';
end;
run;
I hope you can use it, and don't hesitate to ask any further questions.
Hello,
I have the following final table (every day the table contents change):
CARD Table:
The code:
%macro mymail(
from=freetalk@gmail.com,
to=,
acct_no=,
branch_id=,
card=,
id=
);
filename outbox email "freetalk@gmail.com" encoding="utf-8";
data _null_;
file outbox
to=( "&to")
from= ("&from")
subject= "Closing &acct_no - &branch_id";
put "Cancel any instructions in the account &acct_no - &branch_id :" ;
put /;
put " &card - &id";
put /;
run;
%mend;
data _null_;
set CARD;
length cmd $500;
cmd=cats( '%mymail(to=',Mail_to,',acct_no=',Account_Number,',branch_id=',Branch_ID,',card=',Card_No,',id=',ID,')' );
call execute(cmd);
run;
According to the code, they will send 5 emails, but I would like to change that they will only send 4 emails.
When the Branch_ID + Account_Number + ID + Mail_to fields are the same in the CARD table, it will send one email instead of two.
The email will look like this:
The line 2341245543 - 21312 was added to the existing email instead of sending 2 emails.
I would appreciate your help.
I have merged your identical posts.
Hi @shlomiohana
It seems that you can send code in a code box, so you could have added code to generate the input data (as expected in this forum). And the expected email as text or inside a comment in the code box as well. I know how to code it if you provide the input.
hi, the input:
data card;
infile datalines truncover dlm='|' dsd;
input Branch_ID :20. Account_Number :20. ID :20. Card_No :$20. Mail_to :$20.;
datalines;
1|1234567|21312|1231243423|abc@gmail.com
1|1234567|21312|2341245543|abc@gmail.com
12|2342344|23466|8979879879|rer@gmail.com
34|2344523|98986|3453263223|sdr@gmail.com
22|1235534|23214|2353662623|wwt@gmail.com
;
Blank lines in Datalines are a bad idea. Is that actually the code?
When I run that I get this in the log:
156 data card; 157 158 infile datalines truncover dlm='|' dsd; 159 160 input Branch_ID :20. Account_Number :20. ID :20. Card_No :$20. Mail_to :$20.; 161 162 datalines; NOTE: The data set WORK.CARD has 10 observations and 5 variables. NOTE: DATA statement used (Total process time):
Which means there are 5 observations with all missing data and if something is supposed to be done with each observation then you have lots of blank observations to deal with.
@shlomiohana wrote:
hi, the input:
data card; infile datalines truncover dlm='|' dsd; input Branch_ID :20. Account_Number :20. ID :20. Card_No :$20. Mail_to :$20.; datalines; 1|1234567|21312|1231243423|abc@gmail.com 1|1234567|21312|2341245543|abc@gmail.com 12|2342344|23466|8979879879|rer@gmail.com 34|2344523|98986|3453263223|sdr@gmail.com 22|1235534|23214|2353662623|wwt@gmail.com ;
Hi, this is the correct code: (no spaces)
data card;
infile datalines truncover dlm='|' dsd;
input Branch_ID :20. Account_Number :20. ID :20. Card_No :$20. Mail_to :$20.;
datalines;
1|1234567|21312|1231243423|abc@gmail.com
1|1234567|21312|2341245543|abc@gmail.com
12|2342344|23466|8979879879|rer@gmail.com
34|2344523|98986|3453263223|sdr@gmail.com
22|1235534|23214|2353662623|wwt@gmail.com
;
Hi @shlomiohana - thanks for the code.
It is not necessary to use a macro for this. It can all be done in one data step using first. and last. with by-variables to control the beginning of a new mail and sending it before the next mail starts. Remember to enable the File statement in the code when you try it.
I wrote a "real" program also with the usual bells and whistles, it is included as attachment . And I may have sent test mails to your receivers, I am not sure, so I hope they are fictive mail accounts.
data card;
infile datalines truncover dlm='|' dsd;
input Branch_ID :20. Account_Number :20. ID :20. Card_No :$20. Mail_to :$20.;
datalines;
1|1234567|21312|1231243423|abc@gmail.com
1|1234567|21312|2341245543|abc@gmail.com
12|2342344|23466|8979879879|rer@gmail.com
34|2344523|98986|3453263223|sdr@gmail.com
22|1235534|23214|2353662623|wwt@gmail.com
;
run;
* Sort to make sure first. and last. will work as expected in data step;
proc sort data=&_INPUT;
by Branch_ID Account_Number ID Mail_to Card_No;
run;
* Send emails;
%let mail_from = freetalk@gmail.com;
filename outbox email encoding="utf-8";
data _null;
set card (obs=3);
by Branch_ID Account_Number ID Mail_to;
*file outbox;
if first.Mail_to then do;
account = catx(' ', Account_Number, '- 1');
put '!em_subject! Closing ' account;
put "!em_from! &mail_from";
put '!em_to! ' mail_to;
put 'Cancel any instructions in account ' Account_Number / ;
end;
put card_no '-' ID;
if last.Mail_to then do;
put '!em_send!';
put '!em_newmsg!';
put '!em_abort!';
end;
run;
I hope you can use it, and don't hesitate to ask any further questions.
Hi @shlomiohana
I used a real mail address in my full program to test it, and I forgot to change the address before I attached it.
Please remove it from any tests you make.
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.