简体   繁体   中英

How do I retrieve numerical value of macro argument set in data step

I've gone in circles on this one for 1.5 hours, so I'm giving in and asking for help here. What I'm trying to do is dead simple but I cannot for the life of me find a link describing the process.

I have the following data step:

data _null_;
    some_date = "01JAN2000"D;
    call symput('macro_input_date',left(put(some_date),date9.)));
    %useful_macro(&macro_input_date);
run;

where a date value is passed to a macro function (I'm new to these). I'd like to use the numeric value of the date value - let's be wild and say I want to get the value of the year, multiply it by the day value, and subtract the remainder after dividing the month value by 3. I can't seem to get just the year value out of the input. I've tried various things such as

  • symget , both "naked" and prepended with "%", with arguments that represent all possible permutations of the following variants:
    • have a naked reference to the variable, eg macro_input_date
    • enclose in single quotes, eg 'macro_input_date'
    • enclose in double quotes, eg "macro_input_date"
    • prepend with the ampersand, eg &macro_input_date
  • direct call to %sysfunc(year(<argument as variously specified above>)

Can anyone tell me what I am missing?

Thanks!

Given that you asked about macro functions, I'll guess that your example date processing is just an example. Talking about macro functions in general, it's important to understand that a macro function will (generally) not be doing any processing of its own, it will just be generating some data step code to do some task. So, for something like your contrived example, the data step code would be something like:

data out;
  set in; * Assume this contains a numeric called 'some_date';
  result = year(some_date) * day(some_date) - mod(month(some_date), 3);
run;

To macroise this, you don't need to transfer the data values to the macro, you just need to transfer the variable name:

%macro date_func(var=);
  year(&var) * day(&var) - mod(month(&var), 3)
%mend;

data out;
  set in; * Assume this contains a numeric called 'some_date';
  result = %date_func(var=some_date);
run;

Note that the value of the var parameter here is the literal text some_date , not the value of the some_date data step variable. There are other ways to do it of course - you could actually pass this macro a date literal and it would still work:

data out;
  set in; * Assume this contains a numeric called 'some_date';
  result = %date_func(var="21apr2017"d);
run;

so it all depends on exactly what you're trying to do... maybe you want to assign the result to another macro variable, so it doesn't need to be part of a data step at all, in which case you could do a similar thing with %sysfunc functions etc.

If you're just trying to get the year, you would do something like:

data _null_;
    some_date = "01JAN2000"D;
    call symput('macro_input_date',left(put(some_date,date9.)));
    yearval = substr(symget('macro_input_date'),6,4);
    put yearval=;
run;

Your macro value ( &macro_input_date ) is not the actual date value (14610) but is the text 01JAN2000 . So you cannot use the year function (unless you INPUT it back), you would use substr to grab the year part.

Of course, this is all sort of pointless as going to/from macro variable doesn't really accomplish much here.

Are you just have trouble with date literals? Your data step code

data _null_;
  some_date = "01JAN2000"D;
  call symput('macro_input_date',left(put(some_date),date9.)));
run;

is just going to do the same thing as

%let macro_input_date=01JAN2000 ;

Now if you want to treat that string of characters as if it represents a date then you need to either wrap it up as a date literal

"&macro_input_date"d

Or convert it.

%sysfunc(inputn(&macro_input_date,date9))

Why not just store the actual date value into the macro variable?

call symputx('macro_input_date',some_date);

Then it wouldn't look like a date to you but it would look like a date to the YEAR() function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM