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

I am having the following code. I am getting one less observation in the resulting emails. Eg. if cnt is 6, I am sending out 5 emails as result. Can anyone please let me know why this is happening and how to resolve the issue.

%macro mail ;


%do i=1 %to &cnt.;

data _null_;

set ds1;

by name

if _n_=&i.;

call symput('firstname',trim(NAME));

call symput('createdemail',%str("'"||trim(EMAIL)||"'"));

run;


filename MailBox

    EMAIL

    FROM       =   testmail@test.com

  TO    = recepient@gmail.com

  SUBJECT = "Test Subject"

data _null_;

    file MailBox;

    put "Hello &name." ;


%mend mail;

%mail;




1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

Have you tried adding a RUN; statement to end your final DATA step?  SAS usually picks up on this sort of thing ... but since we don't have the context here that might be a possibility.

View solution in original post

9 REPLIES 9
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Hi,

Well your missing a mend in there for the do loop, semicolon after filename etc..  How many records in ds1?  Can I suggest this:

data _null_;

     set ds1;

     call execute('filename MailBox email from= testmail@test.com to= recepient@gmail.com subject="Test Subject";

                            data _null_; file mailbox; put "Hello '||strip(name)||'"; run;');

run;

sasmaverick
Obsidian | Level 7

I just posted a partial piece of the code. The macro is executing, but I am getting one less than the count. That is if &cnt=5, I am getting only 4 emails.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Unfortunately your not giving enough information to go on.  How many records are in the dataset ds1, remember that will define how many bits of code are generated:

data _null_;

set ds1;

by name

if _n_=1;

call symput('firstname',trim(NAME));

call symput('createdemail',%str("'"||trim(EMAIL)||"'"));

run;

...

data _null_;

set ds1;

by name

if _n_=2;

call symput('firstname',trim(NAME));

call symput('createdemail',%str("'"||trim(EMAIL)||"'"));

run;

...


Now in the above if ds1 only has 1 record then the second code will not do anything as _n_ != 2;

sasmaverick
Obsidian | Level 7

65 records in ds1. So 65 emails should go out. But, only 64 are going out

ballardw
Super User

Look at where you are setting &cnt.

Since that variable controls the number of iterations that would be a very likely place for an off by one error.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

What does options mlogic mprint symbolgen; state in the log?  As ballardw has stated &cnt. would appear to be wrong, if indeed there are that many rows in your dataset.  Its hard for us to say as we have no data, nor the program.

Astounding
PROC Star

Have you tried adding a RUN; statement to end your final DATA step?  SAS usually picks up on this sort of thing ... but since we don't have the context here that might be a possibility.

Ron_MacroMaven
Lapis Lazuli | Level 10

As others have suggested the clue is that the macro variable 'cnt'

appears to be equal to the number of obs of the data set you are reading, named 'ds1'.

This is a style issue in macros: accessing global macro variables,

for which the reader has no knowledge.

better: fetch nobs at the top of the macro

I recommend cut&paste the code from macro nobs

Macro nobs - sasCommunity

I support RW9's suggestion of using call execute.

which, btw, can be run in open code, no macro needed.

so the code generated is obvious, i.e. has line numbers

and NOBS read from DS1

place the code for the email in a separate program send-email.sas

so you can test it independently of the loop.

here is the routine:

data _null_

set ds1

call execute(%nrstr('%let parm1=...;) );

call execute(%nrstr('%let parm2=...;) );

call execute(%nrstr("%include 'send-email.sas';")

run;

macro function %nrstr is necessary in order to align the macro assignments with the %include

sasmaverick
Obsidian | Level 7

Hi all,

Thanks for all your replies. I was missing the run statement at the end of the final data step. Thank you Astounding (user)!

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 1294 views
  • 1 like
  • 5 in conversation