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
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?
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.
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;
%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
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.
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 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.