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 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 8925 views
  • 0 likes
  • 6 in conversation