Sorry this is a pick up of a previously answered question.
I understand how to create and reference a macro, (%let macrovalue / ¯ovalue).
However, if I have the results of a function, how does one assign this result to a macro value?
For instance,
Helpful code was provided in my previous query, illustrating how to use INTNX, where variable "prevybeg" was defined as '01JAN2012:0:0:0'dt;
How best would one establish a macro variable using the calculated value of variable "prevybeg"?
Is it best form to just use nested sysfunc's and calculate the macro directly?
%let Start_Date = '06FEB2013:0:0:0'dt;
data _null_;
prevybeg=dhms(intnx('year',datepart(&Start_Date),-1,'b'),0,0,0);
format prevybeg datetime19.;
put prevybeg=;
run;
TS
TS
To work with functions in macro code you need to learn to use %SYSFUNC() macro function.
If you want to keep your macro variables looking like human readable datetime values then perhaps just add the ""DT to convert them into datetime literals later.
For your particular conversion you can use INTNX() function using the DTYEAR interval and eliminate the extra function calls.
%let Start_Date = 06FEB2013:00:00:00;
%let Prev_Begin = %sysfunc(intnx(dtyear,"&start_date"dt,-1,b),datetime19.) ;
I would use the nested %sysfunc if practical. It would at least let me know when I look at the code later that all I wanted was a single macro variable.
I might be tempted to test building it in a data step though to check on building the pieces of a complicated expression. If you have the value in a datastep then either CALL SYMPUT or CALL SYMPUTX would the way to create the macro variable with the desired value.
And if my times are always 0:0:0 I would seriously consider using Date instead of Datetime values to reduce the number of complicated coding bits. Or at least delay as long as possible the conversion.
Would you mind checking my attempt below? Is this a correct use of sysfunc?
prevybeg=dhms(intnx('year',datepart(&Start_Date),-1,'b'),0,0,0);
%let prevybeg = %sysfunc(dhms(%sysfunc(intnx('year',datepart(&Start_Date),-1,'b'),0,0,0));
TS
datepart is also a function and needs a sysfunc
When passing text parameters/modifiers to a function in a macro the quotes are removed, i.e. year and b shouldn't have quotes
%let prevybeg = %sysfunc(dhms(%sysfunc(intnx(year,%sysfunc(datepart(&Start_Date),-1,b),0,0,0))));
?
TS
Try it
Make sure to note what format your macro variable is in and what type the function requires.
Oh sorry I should have specified, I did try it and it did not work.
TS
%let Start_Date =06FEB2013:0:0:0;
%let prevybeg =%sysfunc(putn(%sysfunc(dhms(%sysfunc(intnx(year,%sysfunc(datepart("&Start_Date"dt)),-1,b)),0,0,0)),datetime19.));
%put &prevybeg;
There are a few methods, you could call symput and create a new mvar from that datastep, or you could use eval:
%let mvar=%eval(&mvar. +1);
However, as I suggested in your other post, mvars are not in my opinion the best method of keeping this type of data.
Thanks RW9 however I'm attempting to build on my current understanding in order to familiarize myself with syntax and common practice. I realize there are probably numerable more efficient ways however I currently don't know them.
Conceptually, Macro's variables seemed to be a way to store variables with values which could be used to referenced throughout a given process flow. If there is a better way to do this I'm all ears.
TS
How you work and what you may need to diagnose program issues is a very valid consideration in this type of style choice. I can definitely see the point of dataset storage if I am running programs in a batch mode and want the persistence of actual values without having to try to wade through lots of log type output to examine possible values. You may also need to provide audit trails for such things in some environments.
To work with functions in macro code you need to learn to use %SYSFUNC() macro function.
If you want to keep your macro variables looking like human readable datetime values then perhaps just add the ""DT to convert them into datetime literals later.
For your particular conversion you can use INTNX() function using the DTYEAR interval and eliminate the extra function calls.
%let Start_Date = 06FEB2013:00:00:00;
%let Prev_Begin = %sysfunc(intnx(dtyear,"&start_date"dt,-1,b),datetime19.) ;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.