DATA Step, Macro, Functions and more

issue with %if %then %else %if

Accepted Solution Solved
Reply
Occasional Contributor mj5
Occasional Contributor
Posts: 18
Accepted Solution

issue with %if %then %else %if

I am using the below code that is if suppvar_list has no observation than use the first condition and if it has then second one but it fails

ERROR: There is no matching %IF statement for the %ELSE.
ERROR: A dummy macro will be compiled.

%let suppvar_list=; %if &suppvar_list. ne %then %do; %do j = 1 %to %sysfunc(countw(&suppvar_list.)); %end; %else %do; %do j = 1 %to %sysfunc(countw(&suppvar_list,%str())); %end;
%let curr_var = %scan(&suppvar_list., &j.);
if not missing(&curr_var.) then do;
QNAM = upcase(vname(&curr_var.));
%end;

.

 

AM i doing anything wrong 


Accepted Solutions
Solution
‎11-30-2017 07:30 AM
Super User
Super User
Posts: 7,860

Re: issue with %if %then %else %if

[ Edited ]

Make sure you have %END statements for your %DO statements. Same for your DO and END statement in the SAS code your macrro is generating.

Consistent indentation helps.  I like the treat the nesting of macro code and generated SAS code separate.

%let suppvar_list=;
%if &suppvar_list. ne %then %do;
  %do j = 1 %to %sysfunc(countw(&suppvar_list.));
    %* WHAT GOES HERE ? ;
  %end;
%end;
%else %do;
  %do j = 1 %to %sysfunc(countw(&suppvar_list,%str()));
    %* WHAT GOES HERE ? ;
  %end;  
  %let curr_var = %scan(&suppvar_list., &j.);
if not missing(&curr_var.) then do;
  QNAM = upcase(vname(&curr_var.));
end;
%end;

You probably want something more like this?

%let suppvar_list=;
%if &suppvar_list. ne %then %do j = 1 %to %sysfunc(countw(&suppvar_list.));
  %let curr_var = %scan(&suppvar_list., &j.);
if not missing(&curr_var.) then QNAM = upcase(vname(&curr_var.)) ;
%end;
%else %do;
QNAM=' ';
%end;

 So if you pass in a list of two variables you generate this SAS code?

if not missing(VAR1) then QNAM = upcase(vname(VAR1)) ;
if not missing(VAR2) then QNAM = upcase(vname(VAR2)) ;

So it looks like you want to set QNAM to the name of the last variable that had a non-missing value.

Not sure what the UPCASE(VNAME()) is doing, but perhaps the values in your original macro variables are array references?

View solution in original post


All Replies
Super User
Super User
Posts: 9,227

Re: issue with %if %then %else %if

Yes, basic problem.  You are mixing macro code and datastep code.  Macro is a find replace system which expands your text before the datastep code is compiled and run.  Start your question by providing test data in the form of a datastep and what you want to see out.  Also post any code - full working not a snippet - so that we can see what you are doing.  Otherwise all we can say is what the log says:

ERROR: There is no matching %IF statement for the %ELSE.
Super User
Posts: 6,543

Re: issue with %if %then %else %if

Just in terms of syntax, each %DO requires a matching %END.  So the first %END matches up with the first %DO J=1 %TO ....

 

It does not match up with the %IF %THEN statement.  So %IF %THEN is not yet ended by the time %ELSE appears.

 

Regardless, @RW9 makes a valid point.  This should be mostly a DATA step application, along the lines of:

 

array myvars {*} &suppvar_list;

do _n_=1 to dim(myvars);

   QNAM= or whatever it is that you want to do;

end;

Respected Advisor
Posts: 2,661

Re: issue with %if %then %else %if

[ Edited ]

%let suppvar_list=;

 %if &suppvar_list. ne %then %do;
       %do j = 1 %to %sysfunc(countw(&suppvar_list.));
%end;

.

 

AM i doing anything wrong 


You have two %do commands but only one %end; You need two %end commands. Same for the next block of code which begins with %else

--
Paige Miller
Super User
Posts: 9,611

Re: issue with %if %then %else %if

Proper visual formatting of the code will make your problem obvious, just line up the corresponding %do's and %end's:


%if &suppvar_list. ne
%then %do;
  %do j = 1 %to %sysfunc(countw(&suppvar_list.));
  %end;
%else %do;
  %do j = 1 %to %sysfunc(countw(&suppvar_list,%str()));
  %end;  
  %let curr_var = %scan(&suppvar_list., &j.);
    if not missing(&curr_var.)
    then do;
      QNAM = upcase(vname(&curr_var.));
%end;

You can now see that the %then %do is missing it's %end

The data step if then do also misses an end.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code
Solution
‎11-30-2017 07:30 AM
Super User
Super User
Posts: 7,860

Re: issue with %if %then %else %if

[ Edited ]

Make sure you have %END statements for your %DO statements. Same for your DO and END statement in the SAS code your macrro is generating.

Consistent indentation helps.  I like the treat the nesting of macro code and generated SAS code separate.

%let suppvar_list=;
%if &suppvar_list. ne %then %do;
  %do j = 1 %to %sysfunc(countw(&suppvar_list.));
    %* WHAT GOES HERE ? ;
  %end;
%end;
%else %do;
  %do j = 1 %to %sysfunc(countw(&suppvar_list,%str()));
    %* WHAT GOES HERE ? ;
  %end;  
  %let curr_var = %scan(&suppvar_list., &j.);
if not missing(&curr_var.) then do;
  QNAM = upcase(vname(&curr_var.));
end;
%end;

You probably want something more like this?

%let suppvar_list=;
%if &suppvar_list. ne %then %do j = 1 %to %sysfunc(countw(&suppvar_list.));
  %let curr_var = %scan(&suppvar_list., &j.);
if not missing(&curr_var.) then QNAM = upcase(vname(&curr_var.)) ;
%end;
%else %do;
QNAM=' ';
%end;

 So if you pass in a list of two variables you generate this SAS code?

if not missing(VAR1) then QNAM = upcase(vname(VAR1)) ;
if not missing(VAR2) then QNAM = upcase(vname(VAR2)) ;

So it looks like you want to set QNAM to the name of the last variable that had a non-missing value.

Not sure what the UPCASE(VNAME()) is doing, but perhaps the values in your original macro variables are array references?

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 5 replies
  • 456 views
  • 0 likes
  • 6 in conversation