BookmarkSubscribeRSS Feed
Uknown_user
Quartz | Level 8

Hello,

 

I am trying to loop the macro variable %M. The code is following:

 

%LET last_month_end_dt = 31oct2015:23:59:59.000;

%let num_months=5;

data _null_;

do i = 0 to &num_months - 1;

a = "&last_month_end_dt"d;

format a date9.;

b = intnx('MONTH',a,-i,'end');

ddate = put(b,date9.)||":23:59:59.000";

call symput('ddate',ddate);

%M(TH,ddate);

end;

run;

 

There must be some problem with formatting - any tips how to make this work? Thanks

 

Jiri

9 REPLIES 9
Cynthia_sas
SAS Super FREQ
Hi:
"%M" is not a macro variable. "%M" is a call to a macro program definition, providing 2 parameters: TH and ddate.

All macro programs is generate code. So when you say that %M is not working, you have to explain HOW it's not working.

One of the fundamental rules of macro processing is that the macro facility only generates code. So what do you envision %M is going to do. What will be critical to helping you will be understanding what %M is supposed to do.

Somewhere in your code, I would expect to see:
%macro M(parm1, parm2);
... some code ...
%mend;

So without seeing that, it is hard to comment on your question.

And it looks like the only purpose of the macro invication is to make a macro variable called &ddate, Can you explain what the end result of your program should be and what is in the %M macro program?

cynthia
Uknown_user
Quartz | Level 8

I have a code (macro called M) that does something. It is fed by two variables, as you wrote: TH,ddate. I am trying to avoid mannual running by setting:

 

%let ddate = 31oct2015:23:59:59.000;

 

then

 

 

%let ddate = 30sep2015:23:59:59.000;

 

etc

 

So I created another variable in macro M (ddate) - there originally was just one variable. By looping through i i am trying to avoid manual running the code.

 

The problem is that ddate has value ddate instead of the dates:

 

15 data _null_;

16 do i = 0 to &num_months - 1;

SYMBOLGEN: Macro variable NUM_MONTHS resolves to 5

17 a = "&last_month_end_dt"d;

SYMBOLGEN: Macro variable LAST_MONTH_END_DT resolves to 31oct2015:23:59:59.000

18 format a date9.;

19 b = intnx('MONTH',a,-i,'end');

20 ddate = put(b,date9.)||":23:59:59.000";

21 call symput('ddate',"&ddate"d);

SYMBOLGEN: Macro variable DDATE resolves to 30JUN2015:23:59:59.000

22 %M(TH,ddate);

MLOGIC(M): Beginning execution.

MLOGIC(M): Parameter COUNTRY has value TH

MLOGIC(M): Parameter DDATE has value ddate

 

 

Cynthia_sas
SAS Super FREQ
Hi:
I am so sorry my question was not clear. You said "I have a code (macro called M) that does something." And my question was about the "something" that the macro called M does? What is the full code -INSIDE- the %macro M and the %mend statements? What does the macro %M actually do? No one can help you based on the information you've provided so far.

cynthia
Uknown_user
Quartz | Level 8

I cannot post here the code for macro M. I only need to change the value of ddate from ddate to the dates

30JUN2015:23:59:59.000 when it beginns execution it said:

 

Parameter DDATE has value ddate

 

 

There must be ddate has value 30JUN2015:23:59:59.000

 

gamotte
Rhodochrosite | Level 12

This is only a wild guess as, as Cynthia_sas put, you don't provide the code for the macro function %M.

Doesn't this macro expect a value instead of the name of a macrovariable as its second argument. If so, it should be called as

 

%M(TH,&ddate.);

Cynthia_sas
SAS Super FREQ

Hi:

The problem with trying to use &DDATE as you suggest is that you can't use a macro variable in the same DATA step program where you are creating it. In the example below, my macro program %M is not doing much except a simple PROC PRINT. But if the goal is to run the macro 1 time and only 1 time using 30JUN2015:23:59:59.000 as the value for &ddate, then my program does that. I did not use the DO loop in the program, because I didn't understand why it was needed when all the macro variables in the %LET could have been used inside a single INTNX.

 

As shown in my log, if you try to use &DDATE inside the DATA step program, it will not be resolved. But if you try to use &DDATE after the step boundary, then it will be used. I deleted (with %SYMDEL) the &DDATE macro variable before the program runs, just so it's not in the GLOBAL symbol table from a previous run.

 

cynthia

 

macro_boundary.png

gamotte
Rhodochrosite | Level 12

Yes, of course. Thanks for the correction.

Uknown_user
Quartz | Level 8

Thank you very much for your help. The reason for loop in that data step was to produce all different dates, i.e.:

 

30Jun2016:23:59:000

31Jul2016:23:59:000

30Aug2016:23:59:000

etc...

 

So that I would not have to mannually change %let ddate = 30Jun2016:23:59:000; to %let ddate = 31Jul2016:23:59:000; etc

 

I really appreciate your help. I managed to make a cycle inside macro M so there it is no longer needed to create another data step for looping the dates.

 

Jiri

Reeza
Super User

To call the macro you should be using call execute. In your datastep it doesn't look like TH is ever defined. 

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
  • 9 replies
  • 1162 views
  • 0 likes
  • 4 in conversation