BookmarkSubscribeRSS Feed
deleted_user
Not applicable
perhaps it's because I'm coming from a Visual Basic world, but I am having trouble detciding when if statements need an end; and when they don't. My problems come mainly in nested if logic. For example:

If somecondition then do;
hatever
end;
else if someothercondition then do;
something
end;
else if somethingelse then do;
differentstuff
end;

Will that be OK?

or, another example:

If somecondition then
processA
else
if anothercondition then
if anewcondition then
if onemorecondition then
processB
else
if asecondcondition then
processC
end;
end;
end;

Also, when do you use if..then and when do you use if...then do?

Things like this seem to be my bigger headache at the moment. Like I said, I think it's coming from Visual Basic that is causing me grief.... in VB, the logic appears simpler - If....then.... end if It always looked like you knew where the if statement terminated.

Can anyone help out?
10 REPLIES 10
deleted_user
Not applicable
Take the statements in English and it might make better sense.


If FRED is BALD then HAIRBRUSH = BADGIFT;

If JENNY is FEMALE Then Do;
AFTERSHAVE = BADGIFT;
SALONGIFTCARD = GOODGIFT;
End;


The Do ... End construct is generally used where more than one outcome results from the comparison. Where a single outcome occurs, you can use a single statement.


May I also add that while I used two If statements here, it was because they were unrelated. If I had wanted to test FREDs hair, then test FREDs hair colour, then my second IF should be preceded by an ELSE since they are mutually exclusive. Blindly coding a series of IF statements without considering that some may be excluded by a preceding IF statement leads to lots of compiled and executed statements that don't need to be run each time.

It also makes for code that is much easier to read and understand.

Kind regards

David
LawrenceHW
Quartz | Level 8
Basically, if there's a DO statement you need a matching END statement. In a perfect world SAS would have and ENDIF statement (similar to VB and many other programming languages) but it doesn't.

Your second example doesn't require the 3 x END statements.

In general use IF ... THEN DO; ...; END; statements if you want to perform multiple statements based on the results of the IF clause. If you only need to perform one statement after satisfying an IF clause then the DO ... END is not required.

You might want to indent the code within the DO blocks as this can make it easier for you to read and de-bug.

Hope this helps.
LawrenceHW
Quartz | Level 8
Sorry. Just noticed your example was more complicated than a first scan appeared. You will need the END blocks but only where you have multiple statements to execute after satistying the IF clause.

If somecondition then processA;
else if anothercondition then do;
if anewcondition then do;
if onemorecondition then processB;
else if asecondcondition then processC;
end;
end;
Cynthia_sas
SAS Super FREQ
Hi...in SAS, it's like this:
[pre]
IF somecondition = "TRUE" THEN ;

IF jobcode = "PILOT1" then bonus = salary * 1.10;
ELSE if jobcode = "PILOT2" then bonus = salary * 1.08;
ELSE if jobcode = "PILOT3" then bonus = salary * 1.06;
[/pre]
OR
[pre]
IF somecondition = "TRUE" THEN DO;
one statement;
another statement;
another statement;
END;
[/pre]
However, even though it is verbose, I prefer to do this:

[pre]
IF somecondition = "TRUE" THEN DO;
one statement;
END;
ELSE DO;
alternative statement;
END;
[/pre]
because then everything is enclosed within a DO/END pair and if I have to ADD an action, then I don't accidentally forget the DO or the END when I add the action.
All of the above.applies to issuing of statements within a data step program. One alternative to IF/THEN statements is to use a SELECT statement with WHEN clauses.

If you are talking about "executing" process A or process B as the result of a condition, then you might code this in a single DATA step program:
[pre]
IF somecondition = "TRUE" THEN DO;
LINK ProcessA;
some other statement;
END;
ELSE DO;
LINK ProcessB;
some other other statement;
END;
....more code ....
ProcessA:
.... statements for Process A ....
return;
ProcessB:
....statements for Process B ....
return;
[/pre]

If, however, you are talking about writing macro conditional logic (which is a whole different set of programming environment statements), you would:
[pre]
%macro dorept;
%IF rparm = weekly %THEN %DO;
%let title = 'Weekly Report';
%weekly;
%END;
%ELSE %IF rparm = daily %THEN %DO;
%let title = 'Daily Report';
%daily;
%END;
%mend dorept;

%dorept;
[/pre]

But, in this instance %weekly and %daily are themselves macro programs:
[pre]
%macro weekly;
some code for weekly report ...generally whole steps
%mend weekly;

%macro daily;
some code for daily report ... generally whole steps
%mend daily;
[/pre]

So the answer to your question is that generally, it depends. You need the IF, you need the THEN. If you are only going to execute ONE statement, you will not need the DO. If, however, you are going to execute more than one statement, you will need the DO and when you have a DO, you will also need an END.

cynthia
LawrenceHW
Quartz | Level 8
Cynthia,

You're going to confuse the poor man. It sounds like he's only just started with SAS so I don't know if he's started on SAS Macros yet!

Mind you, yet another comprehensive answer from Cynthia. I think I might give up looking at SAS manuals and just ask Cynthia everything .... it seems easier ;).

The bit about always having DO...END round any IF clause is quite useful from a defensive programming strategy as you can add de-bugging and informational statements. From a good programming practice point of view and for ease of maintenance then this is very good advice.

Cheers,
Lawrence
deleted_user
Not applicable
Well....thank you ALL for replying so nicely and so quickly! That makes better sense now.

Cynthia, I only wish the LINK command would let you jump OUT of a single DATA step, don't you? That would be wonderful.

In any case, again, thanks to you all for your replies!
Cynthia_sas
SAS Super FREQ
Ah, Lawrence...I know from his previous posts that he's already going down the macro road. 😉 (And, my boss jokes about PROC CYNTHIA -- I've just been doing this for a mumblety mumble LONG time.)

And as for the idea of LINK taking you OUT of the data step -- when you wish for THAT, you are ready to move into the world of SAS macro programming.

cynthia
deleted_user
Not applicable
Am I reading that correctly, that macro programming can use LINK to let you jump into/out of different steps?? Tell me more, please?

That sounds promising, since what I want to be able to do is like the following:

%If suchandsuch %then
LINK here;
%else %if someotherthing %then
LINK there;
end;

here:
proc sql;
sql code goes here
quit;

there
proc report;
report code goes here
run;

is that possible or am I just dreaming?? And on top of that, how would I do that sort of thing in a macro? Would it be similar to this:

%If suchandsuch %then
proc sql;
sql code goes here
quit;
%else %if someotherthing %then
proc report;
report code goes here
run;
end;

(Not to worry ... I'm aware my syntax is most likely bad..... I just wanted to CONVEY my questions)
Cynthia_sas
SAS Super FREQ
NO, macro programming could contain a data step program that used LINK, but (as I have indicated in previous postings) this is still the relevant answer to what you say you want (which I understand to be the ability to conditionally execute whole chunks of code based on the value of some macro variable or data step variable value):
[pre]

%macro dorept;
%IF &macvar = something %THEN %DO;
%let title = 'Weekly Report';
proc sql;
sql statements go here;
quit;
%END;
%ELSE %IF &macvar = otherthing %THEN %DO;
%let title = 'Daily Report';
proc report goes here
%END;
%mend dorept;

%dorept;
[/pre]
All macro conditional logic MUST be contained within a SAS macro PROGRAM (a SAS Macro Program is contained within %MACRO and %MEND statements). A macro program is like a big typewriter.

It can type one variable name for you, one statement, part of a statement, a whole step, part of a step, a call to another macro ..... you are probably only limited by your imagination and macro programming skills. You MAY use LINK within a DATA step program. You MAY have a DATA step program contained within a SAS Macro program. But your example, as shown below, would NOT work.
[pre]
%If suchandsuch %then
LINK here;
%else %if someotherthing %then
LINK there;
end;

here:
proc sql;
sql code goes here
quit;

there
proc report;
report code goes here
run;

[/pre]

INSTEAD, you would have something more like this:
[pre]
%macro here;
proc sql;
sql code goes here
quit;
%mend here;
* this code is now invokable as '%here' (without quotes);

%macro there;
proc report;
report code goes here
run;
%mend there;
*this code is now invokable as '%there' (without quotes);

%macro runrept;
%If &macvar = suchandsuch %then %do;
%here;
%else %if &macvar = someotherthing %then %do;
%there;
%end;
%mend runrept;

** this code is now invokable as '%runrept' and since it calls the other 2 macro programs;
** I can invoke all 3 essentially by doing this: ;

%runrept;

[/pre]
Note that we have not talked yet about how &macvar will get values. When you're testing, you will set values for &macvar with %let statements. As a stored process, &macvar will get a value from the client application when the user supplies a value for an input parameter.

I think that you really need to consult with Tech Support on the design of these macro programs if you eventually want to turn this code into a stored process. As always, I recommend a 4 step approach:
1) have a working SAS program that executes correctly in an EG code node or from Display Manager with hardcoded values for all selection criteria;
2) take the program from #1 and "macro-ize" it with macro variables. Test the program in an EG code node or from SAS Display Manager by populating the macro variable values with %LET statements;
3) Turn the program from #2 into a MACRO program and add the MACRO conditional logic that you need to implement to make the macro generate all the outputs that you want.
4) When the MACRO program from #3 is working correctly, THEN and ONLY THEN, turn the #3 program into a stored process.

I know it may seem better to just jump into macro programming and turn out a stored process, but a measured approach through steps 1, 2 and 3 -- outside the realm of stored processes -- will, in my opinion, net you the best results with the least heartache. Debugging macro programs is hard enough when you're looking at the SAS log -- let alone having to deal with a client/server situation and the added complexity of stored processes.

cynthia
deleted_user
Not applicable
Hi, Cynthia,

Understood....I was somewhat hoping I had missed something there, but can confirm I didn't. I'm using the approach of macros within macros, since this dang project I'm working on has many parameters and within these parameters, each can have various combinations (print bname, address, position or print department name or ssn,name, location as well as sort choices as well as different output choices. I'm making progress and am succeeding in getting a few various outputs.

I appreciate all your help and comments.... they have been and are a good learning tool.

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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
  • 10 replies
  • 13222 views
  • 0 likes
  • 3 in conversation