Hi,
I am trying to create macro variable which will have string as below:
"%varexist(sdtmcro.&dsn,var1) and %varexist(sdtmcro.&dsn,var2)"
: %varexist is macro in my directory which finds if variable exist in specified dataset. Var1 and var2 are present in another macro varibale "&variables" macro variable.
e.g. %put &variables= &dsn.var1, &dsn.var2;
In order to get above mentioned string, I am creating variable varcond like below for each variables and then concatenating them together :
data _temp_;
%do i =1 %to %sysfunc(countw(&variables.));
%let var=%scan(&variables.,&i);
varcond= "%"||"varexist(sdtmcro.&dsn,&var)";
output;
%end;
domain="&dsn";
run;
proc sort data=_temp_;
by domain ;
run;
data _temp_;
length varcondn $500.;
do until(last.domain );
set _temp_;
by domain ;
condn=catx(' and ',cond,varcond);
end;
run;
proc sql;
select condn into : condition
from _temp_;
quit;
%put &condition;
&condition gets resolved string "1 and 1" instead of "%varexist(sdtmcro.&dsn,var1) and %varexist(sdtmcro.&dsn,var2)".
Can anyone suggest me solution on not resolve macro %varexist in macro variable &condition?
@petlove wrote:
What will be the best approach to create macro variable which holds the "string" e.g. "%varexist(sdtmcro.&dsn,var1) and %varexist(sdtmcro.&dsn,var2)" and it can be recalled in another program in IF statement?
NOTE:
VAR1 and VAR2 can be any variables which are defined in some other macro variable &VARIABLES. This is not constant macro variable, it changes with dataset name.
Here is a macro that you can in a "functional" mode. That is it emits only part of a statement. So you could use it inside an IF, %IF or assignment statement.
%macro varcond(dsn,varlist);
%local i sep ;
%do i=1 %to %sysfunc(countw(&varlist));
&sep %varexist(&dsn,%scan(&varlist,&i))
%let sep=and;
%end;
%mend varcond;
So you might use it this way.
80 options mprint; 81 %let mydataset=SASHELP.CLASS; 82 %let variables=AGE GENDER ; 83 data _null_; 84 if %varcond(&mydataset,&variables) then put "&mydataset has all of the variables: &variables" 84 ! ; MPRINT(VAREXIST): 3 MPRINT(VARCOND): and MPRINT(VAREXIST): 0 85 else put "&mydataset is missing one or more of the variables: &variables"; 86 run; SASHELP.CLASS is missing one or more of the variables: AGE GENDER NOTE: DATA statement used (Total process time): real time 0.26 seconds cpu time 0.01 seconds 87 88 %let variables=AGE SEX ; 89 data _null_; 90 if %varcond(&mydataset,&variables) then put "&mydataset has all of the variables: &variables" 90 ! ; MPRINT(VAREXIST): 3 MPRINT(VARCOND): and MPRINT(VAREXIST): 2 91 else put "&mydataset is missing one or more of the variables: &variables"; 92 run; SASHELP.CLASS has all of the variables: AGE SEX NOTE: DATA statement used (Total process time): real time 0.34 seconds cpu time 0.00 seconds
Re-run your code, but first issue the command
options mprint;
Then, show us the SASLOG so we can see the error.
There is no error in log.
I am expecting to get &condition resolved to
"%varexist(sdtmcro.&dsn,var1) and %varexist(sdtmcro.&dsn,var2)"
But, it is getting resolved to : "1 and 1"
Thank you.
How can we possibly help, if you won't show us the SASLOG, and we don't have the code to see what %varexist does?
Run the code again, turn on these options
options mprint symbolgen mlogic;
and show us the SASLOG.
Here is the log file
There no %varexist macro anywhere in your log. And what is the %varcond macro shown in the log? Whatever this is, it doesn't relate to your original question.
Also, turn on the options as the first line of your program.
The %PUT statement causes the macro calls to %VAREXIST to execute. Try either of these instead:
%put %superq(condition);
%put _user_; /* this might give you a bit more than what you want to see */
If you want to see the macro variables contents without the macro processor evaluating the macro calls then you need to use macro quoting to prevent it.
Try:
%put %superq(condition);
Or look at it using normal SAS code.
data _null_;
condition=symget('condition');
put condition=;
run;
Thank you Tom for your response.
I tried first option you provided. Now, I see "%varexist(sdtmcro.&dsn,var1) and %varexist(sdtmcro.&dsn,var2)" in log or in program where I recall it.
I am having one more trouble.
In my other program, I am calling this %varcond in %if condition as follow:
%if %varcond(&dsn) %then %do;
proc sort data=sdtmcro.&dsn out=&dsn;
by usubjid ;
run;
%end;
But, I get following error:
ERROR: Required operator not found in expression: %varcond(&dsn)
MLOGIC(VARCOND): %PUT %superq(varcondn)
WARNING: Apparent symbolic reference VARCONDN not resolved.
I expect to run do loop by checking this condition:
%if %varcond %then %do= %if %varexist(sdtmcro.&dsn,var1) and %varexist(sdtmcro.&dsn,var2) %then %do
Please let me know what would resolve this problem.
In my other program, I am calling this %varcond in %if condition as follow:
%if %varcond(&dsn) %then %do;
proc sort data=sdtmcro.&dsn out=&dsn;
by usubjid ;
run;%end;
But, I get following error:
ERROR: Required operator not found in expression: %varcond(&dsn)
MLOGIC(VARCOND): %PUT %superq(varcondn)
WARNING: Apparent symbolic reference VARCONDN not resolved.
Looks like you have a bug in the macro %VARCOND().
The error message says that you are referencing a macro variable named VARCONDN that has not been defined.
Perhaps it is just a typo? Is there perhaps a macro variable named VARCOND and you accidentally added an extra N in the %superq() macro function call?
Thank you Tom. I made respective changes in my program.
When I recall macro in following way, there is no error.
%varcond(LB);
MLOGIC(VARCOND): %PUT %superq(varcond)
%varexist(sdtmcro.LB,LBSTRESC) and %varexist(sdtmcro.LB,LBDRVFL)
However, when I write it in %if condition, I still see this error where "%PUT %superq(varcond)" is blank:
%if %varcond(LB) %then %do;
proc sort data=sdtmcro.&dsn out=&dsn;
by usubjid ;
run;
%end;
LOG:
SYMBOLGEN: Macro variable DSN resolves to LB
ERROR: Required operator not found in expression: %varcond(&dsn)
MLOGIC(VARCOND): %PUT %superq(varcond)
Thank you.
Possibly because of a missing semi-colon?
That could cause the %PUT statement to be waiting for the closing semi-colon so that the %SUPERQ() function does not actually run until after the macro has finished executing?
You are saying semicolon after "%superq(varcond)" this right?
I did put it still shows same error.
Like this?
data _temp_;
domain="&dsn";
%do i =1 %to %sysfunc(countw(&variables.));
%let var=%scan(&variables.,&i);
varcond= "%"||"varexist(sdtmcro.&dsn,&var)";
output;
%end;
run;
data _TEMP2_;
length CONDN $500;
retain CONDN;
set _TEMP_;
CONDN=catx(' and ',CONDN, VARCOND);
call symputx('condition', CONDN);
run;
%put => %superq(condition);
=> %varexist(sdtmcro.&dsn,&var) and %varexist(sdtmcro.&dsn,&var)
You don't need by group processing in your example as variable DOMAIN is a constant;
Thank you Chris.
In my other program, I am calling this %varcond in %if condition as follow:
%if %varcond(&dsn) %then %do;
proc sort data=sdtmcro.&dsn out=&dsn;
by usubjid ;
run;
%end;
But, I get following error:
ERROR: Required operator not found in expression: %varcond(&dsn)
MLOGIC(VARCOND): %PUT %superq(varcondn)
I expect to run do loop by checking this condition:
%if %varcond %then %do should be equal to %if %varexist(sdtmcro.&dsn,var1) and %varexist(sdtmcro.&dsn,var2) %then %do
When I recall macro in following way, there is no error.
%varcond(LB);
MLOGIC(VARCOND): %PUT %superq(varcond)
%varexist(sdtmcro.LB,LBSTRESC) and %varexist(sdtmcro.LB,LBDRVFL)
However, when I write it in %if condition, I still see this error where "%PUT %superq(varcond)" is blank:
%if %varcond(LB) %then %do;
proc sort data=sdtmcro.&dsn out=&dsn;
by usubjid ;
run;
%end;
LOG:
SYMBOLGEN: Macro variable DSN resolves to LB
ERROR: Required operator not found in expression: %varcond(&dsn)
MLOGIC(VARCOND): %PUT %superq(varcond);
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.