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

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 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

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

5 REPLIES 5
RW9
Diamond | Level 26 RW9
Diamond | Level 26

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.
Astounding
PROC Star

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;

PaigeMiller
Diamond | Level 26

%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
Kurt_Bremser
Super User

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.

Tom
Super User Tom
Super User

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?

sas-innovate-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

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