I'm going crazy about my inaptitude to make this code run:
I do not succeed in creating the macro variables ARGUMENT1, ARGUMENT2
I want to concatenate the WORD ARGUMENT with the index of the loop and then execute...
DATA TEST100;
SET TEST END=FINAL;
CALL SYMPUT("ARGUMENT"||COMPRESS(_N_),CATX(",", COMMITTEE,0));
CALL SYMPUT("NOPS",COMPRESS(_N_));
IF FINAL THEN DO;
DO I=1 TO &NOPS;
CALL EXECUTE ('%TEST_DATE("&&ARGUMENT&I")');
/* COMMITTEE=COMMITTEE - &DAYSBACK; */
END;
END;
RUN;
data TEST ;
input MAKE $ COMMITTEE date9. ROUND $ ;
format COMMITTEE weekdate17. ;
cards ;
VW 10APR2017 1ST
LCV 13APR2017 1ST
SKODA 14MAY2017 1ST
AUDI 10JUL2017 1ST
SEAT 01JUN2017 1ST
VW 23OCT2017 2ND
LCV 02OCT2017 2ND
SKODA 24NOV2017 2ND
AUDI 24DEC2017 2ND
SEAT 17NOV2017 2ND
;
run;
%PUT &WDAYS;
OPTIONS MLOGIC MPRINT MINOPERATOR SYMBOLGEN;
%MACRO TEST_DATE(DATE, VORLAUF);
DATA _NULL_;
%GLOBAL DAYSBACK;
%LET C=0;
%LET N=0;
%DO %UNTIL (&N=1 );
%IF (&DATE-&C) IN (&wdays) %THEN %DO;
%LET N=1;
%LET DAYSBACK=&C;
%END;
%LET C=%EVAL(&C+1);
%END;
RUN;
%MEND;
What is the PURPOSE of this macro?
%MACRO TEST_DATE(DATE, VORLAUF); DATA _NULL_; %GLOBAL DAYSBACK; %LET C=0; %LET N=0; %DO %UNTIL (&N=1 ); %IF (&DATE-&C) IN (&wdays) %THEN %DO; %LET N=1; %LET DAYSBACK=&C; %END; %LET C=%EVAL(&C+1); %END; RUN; %MEND;
The data _null_ / run; is not going to do anything as the rest is all macro code. Where is &wdays going to come from?
If the purpose is to adjust a date value by a a number of days then you should investigate the INTNX function to do that directly instead of some ugly looping code.
Also calling macro variables in the same datastep that creates them is problematic at best, usually doesn't work.
After calling you macro in a loop the only value that would remain would be last generated value for DAYSBACK, so the loop makes little sense and this should do most of the same:
DATA _null_; SET TEST END=FINAL; CALL EXECUTE ('%TEST_DATE('||committee||',0)'); RUN;
Thanks, &wdays holds working days of 2017.
I want to check with the data _null_ if the dates coming from the dataset are valid working days.
If not, the macro with the global variable daysback returns how many days I have to advance the meeting in order to coincide with a working day.
I could write this row-specific value for daysback to a macro variable and use it in a data step for adjusting the original date.
I have resolved this specific issue within a data step and it works.
Therefore here the question if it makes sense or not, is not so important for me.
Generally speaking I want to know how I can access a logic, here in format of a macro, within a data step. I had heard of FCMP but I wonder if it's possible, feasible, recommendable to do it like I am trying here...
And more concrete I want to know how I can build the macro variable Argument1 by concatenating ARGUMENT and the DO-LOOP index.
Did you try somthing like %put &argument1 after the data step?
DATA _null_; committee='Some text'; CALL SYMPUT("ARGUMENT"||COMPRESS(_N_),CATX(",", COMMITTEE,0)); RUN; %put &Argument1;
The argument variable was created just fine. It is the use inside the same data step that creates it that is problematic.
Unless you have a very complex definition of "workday" you may find that the existing date functions such as WEEKDAY and HOLIDAY may be easier to program and maintain.
You know that SAS allows you develop your own custom intervals and use that in functions such as INTNX and such?
It isn't as easy as I'd like but it seems easier than what you're doing 🙂
The specific example starts on page 5
https://support.sas.com/resources/papers/proceedings15/2460-2015.pdf
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.