BookmarkSubscribeRSS Feed
TFitz92
Calcite | Level 5

Hi there,

 

I need to create a counter inside of a macro. I can get it to work fine with a data step, but I am having trouble getting it to work inside of the macro. Please could you help, I'm not sure if the %sysfunc is in the wrong place.

 

The code below was my attempt;

 

%let Start_date =%sysfunc(input(%sysfunc(strip(%sysfunc(put(201503,6.))))||'01',yymmdd10.));
%let Curr_Date =%sysfunc(input(%sysfunc(strip(%sysfunc(put(201505,6.))))||'01',yymmdd10.));

%let counter = %sysfunc(intck('month',&Start_date.,&Curr_Date.));
%put &counter.;

%do i = 1 %to &COUNTER.;

 

Thanks in advance. 

 

Note: using EG 7.1

7 REPLIES 7
data_null__
Jade | Level 19

You can't use PUT or INPUT functions with %SYSFUNC use PUTC/PUTN or INPUTC/INPUTN you have other issues quotes where they should not be and concatenation operator.  Do you want the YYYYMM part of the date to be a variable? 

 

34         %let Start_date =%sysfunc(inputn(20150301,yymmdd10));
35         %let Curr_Date  =%sysfunc(inputn(20150501,yymmdd10));
36         %let counter = %sysfunc(intck(month,&Start_date.,&Curr_Date.));
37         %put NOTE COUNTER=&counter.;
NOTE COUNTER=2

 

 

Kurt_Bremser
Super User

Ouch. Use a data step:

%let start=201503;
%let end=201505;

data _null_;
date_start = input("&start.01",yymmdd8.);
date_end = input("&end.01",yymmdd8.);
counter = intck('month',date_start,date_end);
call symput('counter',put(counter,best.));
run;

data_null__
Jade | Level 19

@Kurt_Bremser and @RW9 seem overly dismissive and a bit harsh in reply to @TFitz92 question.  While it might be true that it is much easier do run functions in data steps. Sometimes data steps cannot be used and whether that is the case here or not is irrelevant.

 

I appreciate @Quentin for explaining is detail the issues with the code presented and why it didn't work and how it can be improved.  

Kurt_Bremser
Super User

Once I see 4(!) parentheses in direct succession, I know that somebody is about to outsmart her/himself.

Code like that is a horror to maintain.

 

KISS rules.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

And why do you *need* to do it in macro?  Macro language is a syntax for generating text code which is then operated upon.  It doesn't have the strcutures needed to process data in an efficient way. Datastep is designed to process and manipulate data, hence would be a better fit for manipulating dates.

Now I don't know what the %do loop does or the rest of the code, so can't really advise there, however to get the ouptut:

data _null_;
  call symputx('counter', intck('month',"20150301"d,"20150501"d));
run;

Reads far easier.  Obviously the example would change based on your other code.

Quentin
Super User

@data_null__ already gave the answer, but I'll take a minute to expand on some of the general macro issues.

 

Consider this line:

%let Start_date =%sysfunc(input(%sysfunc(strip(%sysfunc(put(201503​,6.))))||'01',yymmdd10.));

You are trying to make a macro variable, Start_date, which will resolve the the SAS date for March 1, 2015.  A few points:

 

 

1.  In the inner most bit with putc you are trying to make the string 20150301 the pieces 201503 and 01.  In the data step language, you would use the PUT function to convert the numeric value to 201503 to text value "201503", and the concatenator operator to concatenate the text value "01" to that.  But in the macro language all data is text.  So if you want to concatenate 201503 with 01, you can do it with just:

%let SomeDate=20150301;

Okay, that's not clear because it looks like assignment of one value, not concatenation, so perhaps this is a better exmple:

 

%let yyyymm=201503;
%let SomeDate=&yyyymm.01;

With that, &SomeDate will resolve to 20150301.  There is no concactenation operator, and no put function to convert numeric values to chacter, beacuse the macro language all data is just text.  There are also no quotes around "01".  If you add quotes, they will become part of the value of SomeDate and will probably break things.  The macro language is a text manipulation language (used to build SAS code), not a data processing language.

 

 

2.  If you want to convert the text value 20150301 to the text value 20148 (This is the SAS date of March 1, 2015), you can use the INPUTN function. The INPUT function cannot be called by %SYSFUNC.

%let Start_Date=%sysfunc(inputn(20150301,yymmdd8));

3.  The INTCK function is happy to take SAS date literals instead of SAS date values.  This means you can also do something like below:

 

 

%let Start_Date="01MAR2015"d;
%let Curr_Date="01MAY2015"d;
%let Counter = %sysfunc(intck(month,&Start_Date,&Curr_Date));

 

To me, this is an example where the macro solution could actually read clearer than the data step solution, at least to my eyes.

BASUG is hosting free webinars Next up: Mike Sale presenting Data Warehousing with SAS April 10 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
ballardw
Super User

I agree that generally a direct assignment using the date literal format might be best. If this macro is eventually going to be used in such a form that you could pass the year and month a numerals then another option might work.

 

%let Start_date = %sysfunc(mdy(3,1,2015));

%let Curr_date = %sysfunc(mdy(5,1,2015));

The start date would have the numeric value of a SAS date literal which appears to mimic the original intent.

 

If you are going to make the months and years as parameters to a macro call:

%let Start_date = %sysfunc(mdy(&Start_Month,1,&Start_Year));

%let Curr_date = %sysfunc(mdy(&Curr_Month,1,&Curr_year));

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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