Hi:
There is a difference between where and when the %SYSFUNC function with OPEN is resolved and executed and trying to use a %IF in your macro program invocation. The invocation is happening in open code. I don't think there's any quoting function you can use that will mask %IF in the invocation itself.
In your %SYSFUNC example, the &data&where is resolved to something like this, internally, by the macro processor and -THEN- the %SYSFUNC does the work:
%let dsid2=%sysfunc(open(work.old(where=(CO="EMP")),i));
when you switch to a set statement, then you need to generate a statement like one of these to go to the compiler:
set work.old(where=(CO="EMP")); or
set work.old(where=(CO="000"));
By the time the %SYSFUNC hits the syntax compiler, all references to %IF are gone. That is also what must happen with your SET statement. By the time it hits the compiler, all the %IF references must be resolved to syntactically correct code.
The older program that you are trying to modify (from DSID method to SET method) may have to be changed if you want to conditionally set the value of the WHERE statement or clause based on a macro variable. The place to do that might not be in the macro invocation statement, but in the macro program, where %IF is allowed and will be resolved before any other statements get sent to the compiler. Also, you might want to reconsider how you assign a value to the where clause and move to different logic.
How is &WHERE being used as a parameter, currently? In the program that works?? What does the program look like where the DSID method is used? How does &WHERE get assigned a value in that macro invocation??? It probably looks something like this:
%mycall(where=%str(co='EMP'));
or
%mycall(where=co='EMP');
cynthia