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

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?

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

@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

 

View solution in original post

18 REPLIES 18
PaigeMiller
Diamond | Level 26

Re-run your code, but first issue the command

 

options mprint;

Then, show us the SASLOG so we can see the error.

--
Paige Miller
petlove
Obsidian | Level 7

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.

PaigeMiller
Diamond | Level 26

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.

--
Paige Miller
petlove
Obsidian | Level 7

Here is the log file

PaigeMiller
Diamond | Level 26

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. 

--
Paige Miller
Astounding
PROC Star

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 */

Tom
Super User Tom
Super User

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;

 

petlove
Obsidian | Level 7

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.

Tom
Super User Tom
Super User

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?

 

petlove
Obsidian | Level 7

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.

 

Tom
Super User Tom
Super User

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?

 

 

petlove
Obsidian | Level 7

You are saying semicolon after "%superq(varcond)" this right?

 

I did put it still shows same error.

ChrisNZ
Tourmaline | Level 20

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;

petlove
Obsidian | Level 7

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-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
  • 18 replies
  • 1642 views
  • 0 likes
  • 5 in conversation