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

Hello SAS Community!

 

I am trying to make my life easier by implementing DO loops throughout my code because otherwise I will have to run this a bajillion times.  I'm running into an error when I use the %EVAL() function within a variable.

 

I have the following example data set:

Cust_IDStart_DateEnd_DateClassClose_Flag
1231/4/20165/1/2017ACLOSE
4561/27/20162/19/2017BUP
7891/15/20163/20/2019CDOWN


I also created several date variables in an earlier part of my code:

&MonthEnd0 = Jan 1, 2017;

&MonthEnd1 = Jan 31, 2017;

&MonthEnd2 = Feb 28, 2017;

&MonthEnd3 = Mar 31, 2017;

etc.

 

I eventually want to end up with something like the following:

 

Cust_IDStart_DateEnd_DateClassClose_FlagMonth1StatusMonth2Status
1231/4/20165/1/2017ACLOSEOPENOPEN 
4561/27/20162/19/2017BUPOPENUP 
7891/15/20163/20/2019CDOWNOPENOPEN 


I'm trying to run a case statement where if the End_Date falls between the previous MonthEnd variable and the next MonthEnd variable, then it returns the Close_Flag; otherwise, return 'OPEN'.  I want to do this for several months.  So I tried this:

 

 

%macro mymacro;

proc sql;
create table MyTable as 
	select 	Cust_ID,
		%do i=1 %to 10;
		case 
			when End_Date between &&MonthEnd%EVAL(&i.-1) and &&MonthEnd&i. then Close_Flag
			when End_Date > &&MonthEnd&i. then 'OPEN'
			else 'SomethingsWrong'
		end as Month&i.Status,
		%end;
		Class
	from	MyOtherTable;
quit;

%mend mymacro;

%mymacro;

 

I seem to be getting an error at the %EVAL portion of the code-- specifically, it says "Apparent symbolic reference MONTHEND not resolved."  When I comment out that line, the code works.  When I get rid of the %EVAL function, the code works.  But I don't know how to filter between the two dates otherwise without using the %eval function.  Am I missing an ampersand somewhere???

 

Thanks in advance!

 

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

Most  likely, macro language is attempting to resolve &&MonthEnd before even touching %EVAL.  Just compute the %EVAL result first:

 


		%do i=1 %to 10;
                %let k = %eval(&i - 1);
		case 
			when End_Date between &&MonthEnd&k and &&MonthEnd&i. then Close_Flag
			when End_Date > &&MonthEnd&i. then 'OPEN'
			else 'SomethingsWrong'
		end as Month&i.Status,
		%end;

View solution in original post

6 REPLIES 6
Reeza
Super User
You'll need to show more of your code, but your little snippet of how you created your macro variables appears wrong? It sounds like you're classifying data into bins based on months or creating indicator variables for those months? This would work a lot easier within a data step using an array. Is that an option?
Astounding
PROC Star

Most  likely, macro language is attempting to resolve &&MonthEnd before even touching %EVAL.  Just compute the %EVAL result first:

 


		%do i=1 %to 10;
                %let k = %eval(&i - 1);
		case 
			when End_Date between &&MonthEnd&k and &&MonthEnd&i. then Close_Flag
			when End_Date > &&MonthEnd&i. then 'OPEN'
			else 'SomethingsWrong'
		end as Month&i.Status,
		%end;
akim64
Calcite | Level 5

Brilliant.  Why work harder when you can work smarter?  🙂 thank you!

Reeza
Super User
Why not change the loop for i to 0 to 9 instead of 1 to 10?
akim64
Calcite | Level 5

I tried that! But ...

 

Whether I do i = 1 to 10

 

when EndDate between &&MonthEnd%EVAL(&i.-1) and &&MonthEnd&i. then Close_Flag

or whether I do i = 0 to 9

 

when EndDate between &&MonthEnd&i. and &&MonthEnd%EVAL(&i.+1) then Close_Flag

 I would still be running into the same issue with the %EVAL function because I need the next month in the between statement.

Reeza
Super User
Yeah, this would be much easier in a data step, no macros needed and easier to loop. Or using some date logics.

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
  • 6 replies
  • 3599 views
  • 3 likes
  • 3 in conversation