BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
alepage
Barite | Level 11

Hello,

 

I trying to use if and else if condition to define macro variables varname and varname2 but I am unable to check their value.

Does someone can help me with that issue.

 

data _null_;
   set inforcelisting5;
   call execute
   (compbl(cat(
   "Libname dssource ", engine,'"',path,'";',
   '%nrstr(%macro lookuptbl;)',
   '%nrstr(%if %varexist(',strip(fname),',police) %then %do; %let varname=police;%end;)',
   '%nrstr(%else %if %varexist(',strip(fname),',agreement_nbr) %then %do; %let varname=agreement_nbr;%end;)',
   '%nrstr(%else %if ',strip(cie),' eq be %then %do; %let varname2=datechea;%end;)',
   '%nrstr(%mend lookuptbl;)',
   '%nrstr(%lookuptbl;)',
	'%nrstr(%put &=varname &=varname2;)', 
   "Libname dssource clear;"
)));
run;

partial log file:

 

NOTE: CALL EXECUTE generated line.
1 + Libname dssource base"/dwh_actuariat/sasdata/sas2002/be/habi/bel.prod1000.sah1stat.dec2002.data/ ";
NOTE: Libref DSSOURCE was successfully assigned as follows:
Engine: BASE
Physical Name: /dwh_actuariat/sasdata/sas2002/be/habi/bel.prod1000.sah1stat.dec2002.data/
1 + %macro lookuptbl;%if
%varexist(polices,police) %then %do; %let varname=police;%end;%else %if %varexist(polices,agreement_nbr) %then %do; %let
2 The SAS System 13:22 Thursday, September 19, 2024

2 + varname=agreement_nbr;%end;%else %if be eq be %then %do; %let varname2=datechea;%end;%mend lookuptbl;%lookuptbl;%put
&=varname &=varname2;Libname dssource clear;
WARNING: Apparent symbolic reference VARNAME not resolved.
WARNING: Apparent symbolic reference VARNAME2 not resolved.
varname varname2
NOTE: Libref DSSOURCE has been deassigned.

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

@alepage wrote:

Hello,

 

I trying to use if and else if condition to define macro variables varname and varname2 but I am unable to check their value.

Does someone can help me with that issue.

 

data _null_;
   set inforcelisting5;
   call execute
   (compbl(cat(
   "Libname dssource ", engine,'"',path,'";',
   '%nrstr(%macro lookuptbl;)',
   '%nrstr(%if %varexist(',strip(fname),',police) %then %do; %let varname=police;%end;)',
   '%nrstr(%else %if %varexist(',strip(fname),',agreement_nbr) %then %do; %let varname=agreement_nbr;%end;)',
   '%nrstr(%else %if ',strip(cie),' eq be %then %do; %let varname2=datechea;%end;)',
   '%nrstr(%mend lookuptbl;)',
   '%nrstr(%lookuptbl;)',
	'%nrstr(%put &=varname &=varname2;)', 
   "Libname dssource clear;"
)));
run;

partial log file:

 

NOTE: CALL EXECUTE generated line.
1 + Libname dssource base"/dwh_actuariat/sasdata/sas2002/be/habi/bel.prod1000.sah1stat.dec2002.data/ ";
NOTE: Libref DSSOURCE was successfully assigned as follows:
Engine: BASE
Physical Name: /dwh_actuariat/sasdata/sas2002/be/habi/bel.prod1000.sah1stat.dec2002.data/
1 + %macro lookuptbl;%if
%varexist(polices,police) %then %do; %let varname=police;%end;%else %if %varexist(polices,agreement_nbr) %then %do; %let
2 The SAS System 13:22 Thursday, September 19, 2024

2 + varname=agreement_nbr;%end;%else %if be eq be %then %do; %let varname2=datechea;%end;%mend lookuptbl;%lookuptbl;%put
&=varname &=varname2;Libname dssource clear;
WARNING: Apparent symbolic reference VARNAME not resolved.
WARNING: Apparent symbolic reference VARNAME2 not resolved.
varname varname2
NOTE: Libref DSSOURCE has been deassigned.


After cleaning up the log text so it looks a bit more like nice code I get this:

%macro lookuptbl;
   %if %varexist(polices,police) %then %do; 
      %let varname=police;
   %end;
   %else %if %varexist(polices,agreement_nbr) %then %do; 
      %let varname=agreement_nbr;
   %end;
   %else %if be eq be %then %do; 
     %let varname2=datechea;
   %end;
%mend lookuptbl;
%lookuptbl;
%put &=varname &=varname2;
Libname dssource clear;

Which tells me the reason the variables do not exist where you use the %put at the end because they are currently only LOCAL in scope to the macro %lookuptbl.

You can fix this by adding something inside the definition of the macro that generates:

%global varname varname2 ;

I really don't see much reason for this macro definition to be in call execute statements though.

Perhaps provide some PARAMETERS to the macro definition instead of recompiling it with different values of Fname and Cie in the body of the macro.

Maybe something like

%macro lookuptbl (val1=, val2=;
   %if %varexist(&val1.,police) %then %do; 
      %let varname=police;
   %end;
   %else %if %varexist(&val2.,agreement_nbr) %then %do; 
      %let varname=agreement_nbr;
   %end;
   %else %if be eq be %then %do; 
     %let varname2=datechea;
   %end;
%mend lookuptbl;

Then you would just have to call the macro with the val1=fname, val2=cie .

 

If you are naming the library Dssource because you have hard coded the library name into whatever that %varexist macro might be you have also likely made a poor style choice for that macro.

View solution in original post

4 REPLIES 4
ballardw
Super User

@alepage wrote:

Hello,

 

I trying to use if and else if condition to define macro variables varname and varname2 but I am unable to check their value.

Does someone can help me with that issue.

 

data _null_;
   set inforcelisting5;
   call execute
   (compbl(cat(
   "Libname dssource ", engine,'"',path,'";',
   '%nrstr(%macro lookuptbl;)',
   '%nrstr(%if %varexist(',strip(fname),',police) %then %do; %let varname=police;%end;)',
   '%nrstr(%else %if %varexist(',strip(fname),',agreement_nbr) %then %do; %let varname=agreement_nbr;%end;)',
   '%nrstr(%else %if ',strip(cie),' eq be %then %do; %let varname2=datechea;%end;)',
   '%nrstr(%mend lookuptbl;)',
   '%nrstr(%lookuptbl;)',
	'%nrstr(%put &=varname &=varname2;)', 
   "Libname dssource clear;"
)));
run;

partial log file:

 

NOTE: CALL EXECUTE generated line.
1 + Libname dssource base"/dwh_actuariat/sasdata/sas2002/be/habi/bel.prod1000.sah1stat.dec2002.data/ ";
NOTE: Libref DSSOURCE was successfully assigned as follows:
Engine: BASE
Physical Name: /dwh_actuariat/sasdata/sas2002/be/habi/bel.prod1000.sah1stat.dec2002.data/
1 + %macro lookuptbl;%if
%varexist(polices,police) %then %do; %let varname=police;%end;%else %if %varexist(polices,agreement_nbr) %then %do; %let
2 The SAS System 13:22 Thursday, September 19, 2024

2 + varname=agreement_nbr;%end;%else %if be eq be %then %do; %let varname2=datechea;%end;%mend lookuptbl;%lookuptbl;%put
&=varname &=varname2;Libname dssource clear;
WARNING: Apparent symbolic reference VARNAME not resolved.
WARNING: Apparent symbolic reference VARNAME2 not resolved.
varname varname2
NOTE: Libref DSSOURCE has been deassigned.


After cleaning up the log text so it looks a bit more like nice code I get this:

%macro lookuptbl;
   %if %varexist(polices,police) %then %do; 
      %let varname=police;
   %end;
   %else %if %varexist(polices,agreement_nbr) %then %do; 
      %let varname=agreement_nbr;
   %end;
   %else %if be eq be %then %do; 
     %let varname2=datechea;
   %end;
%mend lookuptbl;
%lookuptbl;
%put &=varname &=varname2;
Libname dssource clear;

Which tells me the reason the variables do not exist where you use the %put at the end because they are currently only LOCAL in scope to the macro %lookuptbl.

You can fix this by adding something inside the definition of the macro that generates:

%global varname varname2 ;

I really don't see much reason for this macro definition to be in call execute statements though.

Perhaps provide some PARAMETERS to the macro definition instead of recompiling it with different values of Fname and Cie in the body of the macro.

Maybe something like

%macro lookuptbl (val1=, val2=;
   %if %varexist(&val1.,police) %then %do; 
      %let varname=police;
   %end;
   %else %if %varexist(&val2.,agreement_nbr) %then %do; 
      %let varname=agreement_nbr;
   %end;
   %else %if be eq be %then %do; 
     %let varname2=datechea;
   %end;
%mend lookuptbl;

Then you would just have to call the macro with the val1=fname, val2=cie .

 

If you are naming the library Dssource because you have hard coded the library name into whatever that %varexist macro might be you have also likely made a poor style choice for that macro.

alepage
Barite | Level 11

I have declare the varname and varname2 as global.  Then I don't have any warning.  But I still have the issue with varname which is always blank.

Tom
Super User Tom
Super User

@alepage wrote:

I have declare the varname and varname2 as global.  Then I don't have any warning.  But I still have the issue with varname which is always blank.


From the logic of your macro that means that none of the conditions were met.

Both of the two variables you looked for with %VAREXIST() were not found and the CIE value was not be.

 

Run it first without all of the complications and make sure it works. 

First find the value of FNAME and ENGINE and PATH and CIE you used from your dataset.

 

Then use them to generate the LIBNAME statement and the two %VAREXIST macro calls.

For example if ENGINE as empty and PATH as /home/myname/mydir and the value of FNAME as dssource.fred then run code like

libname dssource '/home/myname/mydir';
%put %varexist(dssource.fred,police);

 

Notice that for your logic to make any sense the value of FNAME in the dataset has to include the libref DSSOURCE that you defined with the LIBNAME statement.  If the value of FNAME was just FRED then your call to %VAREXIST() would need to include the dssource. before the value of FNAME.

 

Also you can run %IF/%THEN logic in open code (without defining a macro) as long as you use %DO/%END blocks and do not attempt to nest them.

 

Tom
Super User Tom
Super User

You are defining the macro LOOKUPTBL to set values into macro variables named VARNAME and VARNAME2, but there is no code that defines VARNAME.  So when LOOKUPTBL runs it will make VARNAME as LOCAL to LOOKUPTBL.  Which means when LOOKUPTBL ends they will no longer exist.

 

You could simple add a couple of %LET statements before your data step to make sure those macro variables already exist when LOOKUPTBL runs so that the %LET statements will update the values of those macro variables.  Then your %PUT after LOOKUPTBL has ended will be able to find them.

 

But why are you using a data step to DEFINE the macro?  Just design the macro to except whatever it is that changes as a normal input.  It looks like that is the value of the FNAME dataset variable.  So perhaps define it with a macro parameter.  Either call it FNAME also or perhaps DATA or DSNAME.  Then in the data step just CALL the macro passing in the value of FNAME.

%macro lookuptbl(fname,cie);
%if not %symexist(varname) %then %global varname;
%if not %symexist(varname2) %then %global varname2;
%if %varexist(&fname,police) %then %let varname=police;
%else %if %varexist(&fname,agreement_nbr) %then %let varname=agreement_nbr;
%else %if (&cie = 'be') %then %let varname2=datechea;
%mend lookuptbl;

data _null_;
   set inforcelisting5;
   call execute
   (catx(' ','libname dssource',engine,quote(trim(path),"'"),';'
   ,'%nrstr(%lookuptbl)(fname=',fname,',cie=',quote(trim(cie),"'"),');'
   ,'%nrstr(%put &=varname &=varname2;)'
   ,'libname dssource clear;'
   ));
run;

Or perhaps pass in the values of ENGINE and PATH also and have the macro do more and the data _null_ step do less.

 

 

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

SAS Enterprise Guide vs. SAS Studio

What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.

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
  • 4 replies
  • 552 views
  • 2 likes
  • 3 in conversation