BookmarkSubscribeRSS Feed
CamRutherford
Fluorite | Level 6

Hello,

 

I'm looking to create macros in SAS that will allow me to quick reference dates in my code.

 

I would like to have the following...

 

Today 

Today Last year

Today 3Mths ago

Today 6Mths ago

Today 9Mths ago

First Day of Prev Month

Last Day of Prev Month

 

 

Thanks,

Cam

 

15 REPLIES 15
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Why would you need macro when there is perfectly good functions for this:

Today                              = today()

Today Last year                = intnx('year',today(),-1)

Today 3Mths ago              = intnx('month',today(),-3)

Today 6Mths ago              ... same

Today 9Mths ago              ... same

First Day of Prev Month    = intnx('day',intnx(month,today(),-1),1,'b')

Last Day of Prev Month    = intnx('day',intnx(month,today(),-1),1,'e')

 

There is never a need to use macro.

CamRutherford
Fluorite | Level 6

Hi,

 

I'd want a macro because I reference these dates a lot and would make my code more aesthetically pleasing.

 

Thanks,

Cam

Kurt_Bremser
Super User

@CamRutherford wrote:

Hi,

 

I'd want a macro because I reference these dates a lot and would make my code more aesthetically pleasing.

 

Thanks,

Cam


If you include my code in your autoexec, no macro is needed. The macro variables will be created in the global symbol table.

"autoexec" could be:

- the autoexec_usermods.sas file in your configuration

- any autoexec.sas file used by a sas start script/command (ie sasbatch)

- in the "custom code" to be sent when a server connection is opened in Enterprise Guide

- in a "autoexec" process flow in your EG projects

CamRutherford
Fluorite | Level 6
How would I reference each date though?
Kurt_Bremser
Super User

call symput creates macro variables. Use the string supplied to the call routine as the first parameter as a macro variable reference, eg &today for todays's date. Note that it is the raw SAS date value (number of days from 01jan1960), hard to read for humans, but very easy to use in comparisons etc.

ballardw
Super User

@CamRutherford wrote:
How would I reference each date though?

I do something along these lines with a call in my autoexec to create a macro variable with a specific format that I use in title statements. The varible created is named prepdate. When I want to use it:

title2 "Prepared on: &prepdate";

 

You don't mention HOW you intend to use any of these variables. Do you want TEXT that is human readable or the Values that are used in comparisons (or possibly both which would work best with 2 variables, one for text and one for value).

RW9
Diamond | Level 26 RW9
Diamond | Level 26

You may believe that macro is more aesthetically pleasing, I would just call it obfuscation.  SAS Programmers should all know or be able to look up the methodology of the various functions within Base SAS - this being the programming language.  They would not however know all about your particular mass of %&'s.  As @Kurt_Bremser has stated you can use the code in a datastep to generate the required macro parameters, but do bear in mind these will be character, and you will always have to convert each time you want to use them further.  For instance, if you wanted yesterday, you would need:

intnx('day',input("&my_today_value",datetime.),-1);

Compare this to simple base SAS:

intnx('day',today(),-1);

Now add up every time you need to do that and you will see the number of processing/characters needed would in many cases exceed the benefit of storing some add-hoc dates.

CamRutherford
Fluorite | Level 6

So can I not create %let satatements for each date I will want to use?

Kurt_Bremser
Super User

@CamRutherford wrote:

So can I not create %let satatements for each date I will want to use?


Of course you can. But look at this:

%let lst_year=%sysfunc(intnx(year,%sysfunc(today()),-1,same),best.);

vs

data _null_;
date = intnx('year',today(),-1,'same');
call symput('lst_year',put(date,best.));
run;

and tell me which is easier to decipher.

 

PS I forgot to mention that both examples create identical macro variables.

CamRutherford
Fluorite | Level 6
DO YOU MEAN...

%let lst_year=%sysfunc(intnx(month,%sysfunc(today()),-1,same)),best.));
Kurt_Bremser
Super User

@CamRutherford wrote:
DO YOU MEAN...

%let lst_year=%sysfunc(intnx(month,%sysfunc(today()),-1,same)),best.));

Yep. Changed my post. My maxim is that if there is more than one %sysfunc in a statement, I switch to a data step to get rid of the %sysfuncs.

This also makes your code easier to maintain, as more complex logic doesn't become as unwieldy in a data step as it does in a macro %let.

Kurt_Bremser
Super User

@RW9 keep in mind that I deliberately use the best. format for my "date" macro variables, so the raw values can be directly used in comparisons and calculations.

Kurt_Bremser
Super User
data _null_;
date = today();
call symput('today',put(date,best.));
date = intnx('year',today(),-1,'same');
call symput('today_lst',put(date,best.));
date = intnx('month',today(),-3,'same');
call symput('today_3m',put(date,best.));
date = intnx('month',today(),-6,'same');
call symput('today_6m',put(date,best.));
date = intnx('month',today(),-9,'same');
call symput('today_9m',put(date,best.));
date = intnx('month',today(),-1,'begin');
call symput('lst_month_1st',put(date,best.));
date = intnx('month',today(),-1,'end');
call symput('lst_month_lst',put(date,best.));
run;

Put that into an include file or into a macro of your choice.

(In case you put it into a macro, use call symputx with 'g')

Shmuel
Garnet | Level 18

data _NULL_;

  /*=== calculate dates ===*/

       dt = today();

       dt_3y = intnx('year',dt,-3,'same');

       dt_3m = intnx('month',dt,-3,'same');

       dt_6m = intnx('month',dt,-6,'same');

       dt_9m = intnx('month',dt,-9,'same');

       dt_fpm =  intnx('month',dt,-1,'beginning');

       dt_lpm =  intnx('month',dt,-1,'end');     /* or = toady() - day(today());  */

 

/*=== assign dates to macro variables ===*/

      call symput('toady',left(dt));

      call symput('dt_3y',left(dt_3y));

      ......     /* choose your macro variable names and assign the dates calculated */

run;

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
  • 15 replies
  • 1839 views
  • 0 likes
  • 5 in conversation