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

Hello,


I have the following final table (every day the table contents change):

CARD Table:

shlomiohana_0-1644691710580.png

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;

shlomiohana_2-1644692062039.png

 

Sorry for the pictures, but the post will be deleted if not automatically.

I would appreciate your help.

1 ACCEPTED SOLUTION

Accepted Solutions
ErikLund_Jensen
Rhodochrosite | Level 12

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.

 

 

View solution in original post

9 REPLIES 9
shlomiohana
Obsidian | Level 7

Hello,


I have the following final table (every day the table contents change):

CARD Table:

shlomiohana_1-1644688911730.png

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:

shlomiohana_2-1644688997888.png

 

The line 2341245543 - 21312 was added to the existing email instead of sending 2 emails.

 

I would appreciate your help.

andreas_lds
Jade | Level 19

I have merged your identical posts.

ErikLund_Jensen
Rhodochrosite | Level 12

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.

 

shlomiohana
Obsidian | Level 7

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
;
ballardw
Super User

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
;

 

shlomiohana
Obsidian | Level 7

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
;
ErikLund_Jensen
Rhodochrosite | Level 12

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.

 

 

ErikLund_Jensen
Rhodochrosite | Level 12

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.

shlomiohana
Obsidian | Level 7
@ErikLund_Jensen Thank you very much 🙂

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 9 replies
  • 1106 views
  • 4 likes
  • 4 in conversation