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

Sorry this is a pick up of a previously answered question.

I understand how to create and reference a macro, (%let macrovalue / &macrovalue).

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

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

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.) ;

View solution in original post

11 REPLIES 11
ballardw
Super User

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.

GalacticAbacus
Obsidian | Level 7

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

Reeza
Super User

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

GalacticAbacus
Obsidian | Level 7

%let prevybeg = %sysfunc(dhms(%sysfunc(intnx(year,%sysfunc(datepart(&Start_Date),-1,b),0,0,0))));

?

TS

Reeza
Super User

Try it Smiley Happy

Make sure to note what format your macro variable is in and what type the function requires.

GalacticAbacus
Obsidian | Level 7

Oh sorry I should have specified, I did try it and it did not work.

TS

slchen
Lapis Lazuli | Level 10

%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;

RW9
Diamond | Level 26 RW9
Diamond | Level 26

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.

GalacticAbacus
Obsidian | Level 7

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

ballardw
Super User

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.

Tom
Super User Tom
Super User

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.) ;

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