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

Hello,

 

I try to define macro variables in an iterative loop. An altough the code underneath does what it should (SAS 9.4), we can expect a warning message "apparent symbolic references not resolved". Actually I have no idea how a more elegant solution might look. Can you help me?

 

%MACRO a(XVAR1=, CCENT=, GCENT=);
%MACRO NAMEP(prefix,maxnum);
	%DO i=1 %to &maxnum;
		&prefix&i
	%END;
%MEND NAMEP;


%if %sysevalf(%superq(XVAR1)=,boolean) = 0 %then %do; 
	%let NXVAR1 = 1;                             
	%do %while(%length(%scan(&XVAR1,&NXVAR1)));
		%let NXVAR1 = %EVAL(&NXVAR1 + 1);
	%end;
	%Let NXVAR1 = %eval(&NXVAR1 -1);
	%Do N1 = 1 %to &NXVAR1;
		%Let a=%scan(&XVAR1,&N1);
		%Let b=%index(&CCENT,&a);
		%Let c=%index(&GCENT,&a);
		%if &b > 0 %then %do;
			%Let X1&N1 = &a.cc;
		%end;
		%else %if &c > 0 %then %do;
			%Let X1&N1 = &a.gc;
		%end;
		%else %do;
			%Let X1&N1 = &a;
		%end;
	%end;
	%let XVAR1n = %namep(&X1,&NXVAR1);
%end;
%else %do;
	%Let XVAR1n = ;
%end;
%put &XVAR1n;

%mend a;

%a(XVAR1=xvar1a xvar1b, CCENT=xvar1b, GCENT=xvar1a);

Bye, Daniel       

1 ACCEPTED SOLUTION

Accepted Solutions
ArtC
Rhodochrosite | Level 12

First as was mentioned by @ballardw embedded macro definitions are not needed and almost always counter productive.  The macro definitions would appear as:

%MACRO NAMEP(prefix,maxnum);
	%DO i=1 %to &maxnum;
		&prefix&i
	%END;
%MEND NAMEP;
%MACRO a(XVAR1=, CCENT=, GCENT=);
%local xvar1n;
....

The better news is that you don't need the %NAMEP macro anyway.  Let's look at your other code a bit.  This portion counts the number of words in &XVAR1.

	%let NXVAR1 = 1;                             
	%do %while(%length(%scan(&XVAR1,&NXVAR1)));
		%let NXVAR1 = %EVAL(&NXVAR1 + 1);
	%end;
	%Let NXVAR1 = %eval(&NXVAR1 -1);

This is simplified with the COUNTW function.

	%let NXVAR1 = %sysfunc(countw( &XVAR1));                            

The call to the %NAMEP is causing an error (unitialized variable because &X1 is not defined).  Since you already have a loop. the definition of &XVAR1N can be moved insite the loop.

		%else %do;
			%Let X1&N1 = &a;
		%end;
	  %let XVAR1n = &xvar1n &&x1&n1;
	%end;
%end;
%else %do;
	%Let XVAR1n = ;
%end;
%put &XVAR1n;

%mend a;

Notice that &XVAR1N is initialized as a local macro variable just below the macro statement. Other cleanup in the macro is possible, but this should get you started.

View solution in original post

5 REPLIES 5
LaurieF
Barite | Level 11

I can't work out exactly what you're trying to do, but is it simply a case of:

	%let XVAR1n = %namep(X1, &NXVAR1);
RW9
Diamond | Level 26 RW9
Diamond | Level 26

What exactly is it your trying to do?  I can guarentee you thre is a far simpler and easier to maintain way of doing things thatn that, be it re-modelling your data, or using inbuilt SAS functionality.  Creating endless macro lists, macros and such like is a recipe for obfuscatd, unmaintable code which will fall over every time you run it.

ballardw
Super User

Defining a macro to include another macro, especially one such as your NAMEP that has no dependencies on the parameters of the outmacro is poor practice. As a minimum you waste compute cycles recompiling it everytime the outer macro executes.

 

And it really helps to provide an example of what you expect this macro to produce.

ArtC
Rhodochrosite | Level 12

First as was mentioned by @ballardw embedded macro definitions are not needed and almost always counter productive.  The macro definitions would appear as:

%MACRO NAMEP(prefix,maxnum);
	%DO i=1 %to &maxnum;
		&prefix&i
	%END;
%MEND NAMEP;
%MACRO a(XVAR1=, CCENT=, GCENT=);
%local xvar1n;
....

The better news is that you don't need the %NAMEP macro anyway.  Let's look at your other code a bit.  This portion counts the number of words in &XVAR1.

	%let NXVAR1 = 1;                             
	%do %while(%length(%scan(&XVAR1,&NXVAR1)));
		%let NXVAR1 = %EVAL(&NXVAR1 + 1);
	%end;
	%Let NXVAR1 = %eval(&NXVAR1 -1);

This is simplified with the COUNTW function.

	%let NXVAR1 = %sysfunc(countw( &XVAR1));                            

The call to the %NAMEP is causing an error (unitialized variable because &X1 is not defined).  Since you already have a loop. the definition of &XVAR1N can be moved insite the loop.

		%else %do;
			%Let X1&N1 = &a;
		%end;
	  %let XVAR1n = &xvar1n &&x1&n1;
	%end;
%end;
%else %do;
	%Let XVAR1n = ;
%end;
%put &XVAR1n;

%mend a;

Notice that &XVAR1N is initialized as a local macro variable just below the macro statement. Other cleanup in the macro is possible, but this should get you started.

Daniel_Paul
Obsidian | Level 7

Thank you for the valuable thoughts and the time that you have spent on my problem.

 

For the sake of completeness here the working code:

 

%MACRO a(XVAR1=, CCENT=, GCENT=);
%local xvar1n;
%if %sysevalf(%superq(XVAR1)=,boolean) = 0 %then %do; 
	%let NXVAR1 = %sysfunc(countw(&XVAR1));                             
	%Do N1 = 1 %to &NXVAR1;
		%Let a=%scan(&XVAR1,&N1);
		%Let b=%index(&CCENT,&a);
		%Let c=%index(&GCENT,&a);
		%if &b > 0 %then %do;
			%Let X1&N1 = &a.cc;
		%end;
		%else %if &c > 0 %then %do;
			%Let X1&N1 = &a.gc;
		%end;
		%else %do;
			%Let X1&N1 = &a;
		%end;
		%let XVAR1n = &XVAR1n &&X1&N1;
	%end;
%end;
%else %do;
	%Let XVAR1n = ;
%end;
%put &XVAR1n;
%mend a;

%a(XVAR1=xvar1a xvar1b, CCENT=xvar1b, GCENT=xvar1a);

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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.

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
  • 5 replies
  • 755 views
  • 1 like
  • 5 in conversation