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

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.

 

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

@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.

View solution in original post

9 REPLIES 9
Reeza
Super User

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. 

Shmuel
Garnet | Level 18

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.

Kurt_Bremser
Super User

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);
ybz12003
Rhodochrosite | Level 12

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);

 

 

ballardw
Super User

@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??

Kurt_Bremser
Super User

@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.

Tom
Super User Tom
Super User

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)

 

RW9
Diamond | Level 26 RW9
Diamond | Level 26

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?

 

ybz12003
Rhodochrosite | Level 12

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

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 9 replies
  • 1628 views
  • 4 likes
  • 7 in conversation