sas >> Open %If not valid

by abose » Tue, 09 Oct 2007 17:20:44 GMT

Why is %if code not valid unless inside a macro?
How do you workaround this limitation? Is there any way I can turn it


sas >> Open %If not valid

by jim4stat » Tue, 09 Oct 2007 18:57:16 GMT

Hi Arnab,

That is how it is and can not be changed.
An example workaround for e.g.
%IF (&MacroVar EQ Value) %THEN %LET Result = 1;
%ELSE %LET Result = 2;
%LET Result = %EVAL (2 - (&MacroVar EQ Value));

Regards - Jim.

sas >> Open %If not valid

by Tree Frog » Tue, 09 Oct 2007 19:02:35 GMT

Hi Arnab

Someone else will have the scoop on why it is so.

In other news, what are you trying to do? It's likely there are many
ways to "workaround this limitation" without needing to use %if inside
a macro, depending on your circumstances.

Tell us more...

Tree Frog

Open %If not valid

by RHOADSM1 » Tue, 09 Oct 2007 20:17:25 GMT

Jim is correct. This is because %IF is a macro statement, and (with a
few exceptions) macro statements can only be used inside macros. This
is similar to the restriction that DATA step statements (IF, ARRAY,
etc.) can only be used within a DATA step. While there are some
"global" statements in SAS (TITLE, OPTIONS, etc.), most statements only
have meaning within a particular context / environment.

Jim has a good solution for one example of where you might want an %IF
statement in open code. Another common situation is where you might
want to use a macro variable to conditionally execute a step, e.g.:

/* This does not work */
%IF DebugFlag = 1 %THEN %DO;

You can work around this by wrapping the affected code (or even your
entire program) in a "dummy" macro, and then executing the macro:

/* This does work */
%MACRO MyProgram;
%IF DebugFlag = 1 %THEN %DO;
%MEND MyProgram;

Mike Rhoads

-----Original Message-----
On Behalf Of Jim Groeneveld
Sent: Tuesday, October 09, 2007 6:57 AM
Subject: Re: Open %If not valid

Hi Arnab,

That is how it is and can not be changed.
An example workaround for e.g.
%IF (&MacroVar EQ Value) %THEN %LET Result = 1;
%ELSE %LET Result = 2;
%LET Result = %EVAL (2 - (&MacroVar EQ Value));

Regards - Jim.

Open %If not valid

by gerhard.hellriegel » Tue, 09 Oct 2007 20:25:00 GMT

Is that a serious question? In that case I'd expand that: why is the SAS
programming language not valid outside of SAS? Why does SAS not understand
french? Why ...?

Why are some data-step statements not valid in PROC PRINT? Any
circumvention? Yes, use a DATA - step for that!

And use a MACRO, if you want to program with macro-language! Just that


Open %If not valid

by tobydunn » Tue, 09 Oct 2007 22:29:51 GMT

Arnab ,

%Macros job is to create SAS code, nothing more nothing less. While SI could have made the Macro language well completely different they choose not to and instead make it pretty darn close to the Data Step Language (syntactically). Whether you agree with this choice or not well is irrelevant what is done is done.

Data Step and Proc code is from a philisophical standpoint a space seperated (with a few exceptions) language where words have meaning. Obviously there will be times when you dont want SAS to try to interprete the text with meaning. There for it is the job fo the programmer to use single or double quotes around the text which you do not want SAS to interpret.

The macro language while syntactically similar in many ways has a different philisophical base. In the macro facility every thing is onsidered just text and SAS does not try to interpret any thing as having meaning. And it is the job of the programmer to tell SAS what to interpret and what to consider as just text. This is done by % and & prefixing certain words.

Toby Dunn

Compromise is like telling a lie, it gets easier and easier. Each compromise you make, that becomes your standard.

Perfection doesnt exist, once you reach it, its not perfect anymore. It means something else.

Help yourself to FREE treats served up daily at the Messenger Caf Stop by today.

Open %If not valid

by nospam » Wed, 10 Oct 2007 05:19:13 GMT

Even if %if (and %then and %else) were permitted in open code, the
predicated code would have to be valid in that context. So it would be
limited to global statements like %LET, %PUT, TITLE, OPTIONS.

The combination of %SYSFUNC and the IFC function can probably provide
workarounds in many cases. For example, instead of (pseudocode)

%if [today is Tuesday] %then title 'This';
%else title 'That';


"%sysfunc(ifc(%sysfunc(weekday(%sysfunc(today() ) ) )=3,This,That) )";

Open %If not valid

by abose » Wed, 10 Oct 2007 09:52:51 GMT

Thanks for your answers. Still, it seems like it is one of the
shortcomings of the SAS language. Granted macro statements are for
generating texts, but I don't see any reason why open %If, %Do, etc.
cannot be used to create code.

Gerhard, I'd like to address you specifically, because it seems you
haven't got the point at all. Having %If outside a macro is a
convenience feature, and it fits into the language nicely and
unambiguously. Also it seems to me that the change in the language
design would be minimal to uplift this restriction (in fact, it might
easily be the case that it is more of an effort to apply this
restriction rather than not to have it at all). On the other hand, for
example, having a data statement on Proc Print will create more
problems than it will solve - because it is not quite clear how it
should operate. If I put a variable declaration should it change the
actual data? What should be the exact syntax? How complex statements
can I have? For example can I emulate multiple set statements? etc.

You see, the case of allowing open %if is without any such ambiguity
or questions - it seems more natural an 'extension' (if you call it)
to the language.

It's too bad that we cannot turn this 'feature' of not allowing open
%If off.

Thanks all for also suggesting alternatives. Personally, I favor
having something like this:
%Macro iif(Condn,Expr1,Expr2);
%If &Condn %Then &Expr1; %Else &Expr2;

Having this macro in your standard set of macros makes simple open if
statements easy, without clutter of enclosing the code within %Macro
%Mend. For example we can now write:
Title %iif(day eq 'Tuesday','This','That');


Open %If not valid

by iw1junk » Wed, 10 Oct 2007 10:06:45 GMT

Summary: Questions about %IF answered

Here are Arnab's < XXXX@XXXXX.COM > questions with answers.

1) Why is %if code not valid unless inside a macro?

Although I have never seen this expressed in documentation or messages
other than mine, there are two macro languages.

In the first some macro statements can be immediately interpreted and
executed when encountered. %LET and %PUT statements are the primary
examples in addition to macro expression evaluation.

In the second macro statements go through a compile (or interpreted
phase) for later execution via macro invocation. %IF belongs to the
second language. Why? because it is easier to program and it
probably doesn't matter much.

(The statement, "%LET &EQUAL_EXPRESSION;", is an example of a
statement that can be executed in open code when the value of
EQUAL_EXPRESSION is appropriate, but it cannot appear in a macro,
since &EQUAL_EXPRESSION is not evaluated at the time the %LET
statement is compiled and a %LET statement requires the =-symbol for

2) How do you workaround this limitation?

I don't know of any place where one could not replace a "open %IF", if
you had it, with a macro call containing that same %IF statement when
the consequent is SAS code. Consequently, the first answer is a
question - what limitation? Moreover, I would suggest that if one had
an "open" %IF statement it would lead to very poorly designed SAS
programs. Hence I think you should learn to think and work with the
perceived limitation rather than around it.

On the other hand, I feel that if's in general contribute to the
difficulty of reading code. Consequently I am interested in knowing
how to eliminate if's in general.

One technique is a misuse of *-comments. For example, consider:

%let which = ;
&which code ;

As given the last SAS statement is active. Change the first line to

%let which = * ;

and the last line is now a comment, i.e. inactive. Hence control of
the first line determines whether the last line is executed or not.
If you had two such variables you could make a true decision of which
code block to use.

A more general technique is provided by arrays of macro variables.

%let which = 2 ;
%let choice1 = %str(first code block;) ;
%let choice2 = %str(second code block;) ;
%let choice3 = %str(third code block;) ;

In this case the second code block is executed. Again the WHICH
variable at the top controls the decision.

Neither of these techniques produce a very readable style of
programming. Each has a place where it can be best, but the main
interest is academic rather than practical, so I would suggest that
you learn the value of parameter driven macros to generate good SAS
code in a readable manner. In the long run you will be better off
than trying to escape the macro language.

3) Is there any way I can turn it off?

Probably, if you can direct SAS Institute or simply stop using SAS.
Otherwise, no.

Ian Whitlock

Open %If not valid

by rjf2 » Wed, 10 Oct 2007 21:31:41 GMT

> From: abose

DATA _Null_;
if 0 then call execute('%nrstr(*statement1;)');
else if 1 then call execute('%nrstr(*statement2;)');

NOTE: CALL EXECUTE generated line.
1 + *statement2;

the above is not as concise as

%if 1 %then %do; *statement2; %end;

but it shows how to do what you want.

Ron Fehd the macro maven CDC Atlanta GA USA RJF2 at cdc dot gov

Open %If not valid

by datanull » Wed, 10 Oct 2007 22:01:44 GMT

It is my opinion that these sort of trivial macros are more trouble
than they are worth. From time to time someone will post a macro that
references %WORDS,
%GETSOMEHTING, various others I can't remember. I just do see the
point. Your trivial macro call can be replaced with a call to the SAS
IFC function.

title "%sysfunc(ifC(%sysfunc(today(),downame3) eq TUE,This,That))";

While this may seem more complex, it is completely documented within
the SAS system. No need to figure out what %IFF is or where %IFF is
located and the try to understand how and if it works.

Similar Threads

1. PROC EXPORT error "DBMS type EXCEL2000 not valid for export"

Hi all:

  I tried to export a SAS dataset to EXCEL and got some error message:

1606  proc export
1607    data=BackDateInfo
1608    outfile="D:\BackDateInfo.XLS"
1609    DBMS=EXCEL2000
1610    replace;
ERROR: DBMS type EXCEL2000 not valid for export.

  How do I fix it?  I am using Excel Professional Edition 2003.


2. ERROR: The value 205DAI is not a valid SAS name

3. %sysrput macro var not valid macro emission

Macro aficionados :

I'm more confused than usual.  Why may I not emit the value of &remote_var =
from %two ?  See log below code where an error is noted because SAS leaves =
the "4" lying about. =20

Following the log is another example without using rsubmit.  Not exactly th=
e same, but not materially different in my little mind.  Note the "need thi=
s semi-colon before the RSUBMIT, why?" is a secondary question if you're wi=
lling and able to explain the requirement for the extra semi-colon.

Help the Harry

%symdel remote_var;
options mprint;
    options mprint;
        %macro one;
                %sysrput remote_var =3D 4;
        %mend one;

%macro two;
   ;  %* need this semi-colon before the RSUBMIT, why? ;
   %put Inside %nrstr(%two &remote_var) has a value of &remote_var;
%mend two;

%put Result of %nrstr(%two) is %two;;
%put %nrstr(&remote_var) is &remote_var;

2501  %symdel remote_var;
2502  options mprint;
2503  rsubmit;
NOTE: Remote submit to _SERVER_ commencing.
572      options mprint;
573      %macro one;
574          %sysrput remote_var =3D 4;
575      %mend one;
NOTE: Remote submit to _SERVER_ complete.
2505  %macro two;
2506     ;  %* need this semi-colon before the RSUBMIT, why? ;
2507     rsubmit;
2508       %one;
2509     endrsubmit;
2510     %put Inside %nrstr(%two &remote_var) has a value of &remote_var;
2511     &remote_var
2512  %mend two;
2514  %put Result of %nrstr(%two) is %two;;
Result of %two is
MPRINT(TWO):   rsubmit
NOTE: Remote submit to _SERVER_ commencing.
576   %one;
NOTE: Remote submit to _SERVER_ complete.
MPRINT(TWO):  ; %one;
MPRINT(TWO):   endrsubmit;
Inside %two &remote_var has a value of 4
NOTE: Line generated by the macro variable "REMOTE_VAR".
1         4

ERROR 180-322: Statement is not valid or it is used out of proper order.

2515  %put %nrstr(&remote_var) is &remote_var;
&remote_var is 4

This works:

%global var;
%macro local_one;
   %let var =3D 4;

%macro local_two;

%put %nrstr(%local_two) returns %local_two;

2539  %global var;
2540  %macro local_one;
2541     %let var =3D 4;
2542  %mend;
2544  %macro local_two;
2545    %one;
2546    &var
2547  %mend;
2549  %put %nrstr(%local_two) returns %local_two;
%local_two returns 4


This e-mail may be privileged and/or confidential, and the sender does not =
waive any related rights and obligations.
Any distribution, use or copying of this e-mail or the information it conta=
ins by other than an intended recipient is unauthorized.
If you received this e-mail in error, please advise me (by return e-mail or=
 otherwise) immediately. =20

Ce courrier =E9lectronique est confidentiel et prot=E9g=E9. L'exp=E9diteur =
ne renonce pas aux droits et obligations qui s'y rapportent.
Toute diffusion, utilisation ou copie de ce message ou des renseignements q=
u'il contient par une personne autre que le (les) destinataire(s) d=E9sign=
=E9(s) est interdite.
Si vous recevez ce courrier =E9lectronique par erreur, veuillez m'en aviser=
 imm=E9diatement, par retour de courrier =E9lectronique ou par un autre moy=

4. "not a valid SAS name"

5. ERROR: DBMS type EXCEL not valid for export????

Hi All,

Why do I keep getting the error message below when I try to export data to excel?


>>>>           OUTFILE= "J:\PAL 2009\High School Reliability.xls"

>>>>>ERROR: DBMS type EXCEL not valid for export.

6. ERROR: The value 3 is not a valid

7. SAS files not opening


I am not being able to open SAS files in the enhanced editor. eg I drag
and drop a file into the enhanced editor nothing shows up , its just
opens a  new window with the file name and rest is blank. However when
I drag and drop a SAS file into the normal editor the code appears. Any
one understanding why ? like some registry settings or some files not
registered .  My work around is  I drag drop into the normal editor and
then copy it and paste it into the enhanced editor :).

your help or suggestion  is awaited and would be appreciated.


8. How to have RTF files automatically save and not ask to open in