## %IF %Then%do macro doesn't work?

Solved
Super Contributor
Posts: 297

# %IF %Then%do macro doesn't work?

Hello:

I have a regular SAS program, and I would like to creat a macro base on its condition.  However the Log shows an error massage, please help.

data dataout;

set datain;

if prxmatch("m/BDS/i",&var) > 0 then found=1;

else if prxmatch("m/lab_cdate/i",&var) > 0 then found=2;

else if prxmatch("m/lab_de_notes/i",&var) > 0 then found=3;

else if prxmatch("m/lab_den_pcr_perf/i",&var) > 0 then found=4;

else found=0;

run;

%macro prescreen;

data dataout;

set datain;

%if prxmatch("m/BDS/i",&var) > 0 %then %do; found=1;

%if prxmatch("m/lab_cdate/i",&var) > 0 %then %do; found=2;

%if prxmatch("m/lab_de_notes/i",&var) > 0 %then %do; found=3;

%if prxmatch("m/lab_den_pcr_perf/i",&var) > 0 %then %do; found=4;

%end;

%else %do; found=0;

%end;

%mend;

ERROR: There were 3 unclosed %DO statements. The macro PRESCREEN will not be compiled.

ERROR: A dummy macro will be compiled.

Accepted Solutions
Solution
‎06-09-2017 10:25 AM
Super User
Posts: 6,962

## Re: %IF %Then%do macro doesn't work?

ybz12003 wrote:

Thanks for your great suggestion.  I have another problem.  I created some macros first.  How to change the () name after 'Precscreen' below.

%let Var=Newvar;

%let DataIN=pose;

%let DataOUT=UNmatch;

%macro prescreen(datain,dataout,var);

data MS.&dataout;

set MS.&datain;

if prxmatch("m/BDS/i",&var) > 0 then found=1;

else if prxmatch("m/lab_cdate/i",&var) > 0 then found=2;

else if prxmatch("m/lab_de_notes/i",&var) > 0 then found=3;

else if prxmatch("m/lab_den_pcr_perf/i",&var) > 0 then found=4;

else found=0;

run;

%mend;

%prescreen(POSE,UNmatch,Newvar);

The three macro parameters from the macro definition are assigned the three texts you wrote in the macro call. Therefore the three %let's before the macro definition are not needed and in fact useless.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers

All Replies
Super User
Posts: 17,890

## Re: %IF %Then%do macro doesn't work?

The error is clear. You have three %do without any matching %end for them.

Also, your logic doesn't make sense. There no reason to make this into a macro that can be seen.

Posts: 1,397

## Re: %IF %Then%do macro doesn't work?

[ Edited ]

Each %DO needs its %END.

You have more %DO then %END - thats the error.

Besides, entering a data atep in macro doesn't need change IF into %IF.

And I dont see any reason to put the data step into %maco program, unless you

supply arguments by macro variables.

Super User
Posts: 6,962

## Re: %IF %Then%do macro doesn't work?

Very simple. Every %do needs a corresponding %end.

But you need to be aware that your macro won`t work, as the variable that is pointed to by &var is not present when the macro executes.

Since the only thing that is dynamic in your code is the variable name provided through &var, you don't need the macro at all.

Or you should keep the code as it is, and just provide var as a macro parameter:

%macro prescreen(datain,dataout,var);
data &dataout;
set &datain;
if prxmatch("m/BDS/i",&var) > 0 then found=1;
else if prxmatch("m/lab_cdate/i",&var) > 0 then found=2;
else if prxmatch("m/lab_de_notes/i",&var) > 0 then found=3;
else if prxmatch("m/lab_den_pcr_perf/i",&var) > 0 then found=4;
else found=0;
run;
%mend;

%prescreen(have,want,some_variable_name);
---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super Contributor
Posts: 297

## Re: %IF %Then%do macro doesn't work?

Thanks for your great suggestion.  I have another problem.  I created some macros first.  How to change the () name after 'Precscreen' below.

%let Var=Newvar;

%let DataIN=pose;

%let DataOUT=UNmatch;

%macro prescreen(datain,dataout,var);

data MS.&dataout;

set MS.&datain;

if prxmatch("m/BDS/i",&var) > 0 then found=1;

else if prxmatch("m/lab_cdate/i",&var) > 0 then found=2;

else if prxmatch("m/lab_de_notes/i",&var) > 0 then found=3;

else if prxmatch("m/lab_den_pcr_perf/i",&var) > 0 then found=4;

else found=0;

run;

%mend;

%prescreen(POSE,UNmatch,Newvar);

Super User
Posts: 10,526

## Re: %IF %Then%do macro doesn't work?

ybz12003 wrote:

Thanks for your great suggestion.  I have another problem.  I created some macros first.  How to change the () name after 'Precscreen' below.

Change what???

The () are required to show they are the macro parameters. Since you have 3 parameters "named" is that what you are looking for how to change NewVar to a different variable name??

Solution
‎06-09-2017 10:25 AM
Super User
Posts: 6,962

## Re: %IF %Then%do macro doesn't work?

ybz12003 wrote:

Thanks for your great suggestion.  I have another problem.  I created some macros first.  How to change the () name after 'Precscreen' below.

%let Var=Newvar;

%let DataIN=pose;

%let DataOUT=UNmatch;

%macro prescreen(datain,dataout,var);

data MS.&dataout;

set MS.&datain;

if prxmatch("m/BDS/i",&var) > 0 then found=1;

else if prxmatch("m/lab_cdate/i",&var) > 0 then found=2;

else if prxmatch("m/lab_de_notes/i",&var) > 0 then found=3;

else if prxmatch("m/lab_den_pcr_perf/i",&var) > 0 then found=4;

else found=0;

run;

%mend;

%prescreen(POSE,UNmatch,Newvar);

The three macro parameters from the macro definition are assigned the three texts you wrote in the macro call. Therefore the three %let's before the macro definition are not needed and in fact useless.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super User
Posts: 6,502

## Re: %IF %Then%do macro doesn't work?

[ Edited ]

If you want to use the values of your macro varibles in the call to your macro then just expand them the same way your would reference the values of those macro variables anywhere else.

%let Var=Newvar;
%let DataIN=pose;
%let DataOUT=UNmatch;

%prescreen(&DataIn,&DataOUT,&Var);

Also one of the nice things about SAS macros is that you can assign the values by name in the call , even when the parameters are defined as positional in the macro definition.  This makes the program with the macro call easier to read since you can see the parameter name and not just its position. In fact with named parameter values in the call you can order the parmeters how ever you want in the call.

%prescreen(var=Newvar,datain=pose,dataout=UNmatch)

Super User
Posts: 7,413

## Re: %IF %Then%do macro doesn't work?

You are making a common mistake of mixing Dataset code with Macro code.  %if constructs are part of the macro language, not datastep.

%macro prescreen;
data dataout;
set datain;
if prxmatch("m/BDS/i",&var) > 0 then found=1;
if prxmatch("m/lab_cdate/i",&var) > 0 then found=2;
if prxmatch("m/lab_de_notes/i",&var) > 0 then found=3;
if prxmatch("m/lab_den_pcr_perf/i",&var) > 0 then found=4;
else found=0;
%end;
%mend;

However I totally agree with @Reeza as I don't see any value in macro-tizing this?

Super Contributor
Posts: 297

## Re: %IF %Then%do macro doesn't work?

Thanks for all your great help.  I got it work.

☑ This topic is SOLVED.