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

Hello community,

 

I hope you can give me some advice regarding a programming issue. My goal is to find the forelast workday in a month. I assume, that every Monday till Friday is a workday and do not care about feast day. In the macro var load_day is the last workday of the month given.

Ah...I'm working with EG 7.12 HF1 which is SAS 9.4 M2.

 

This is the code I have this far:

 

/* calculate the last workday before the given load_day */
options mlogic mprint symbolgen minoperator;


%global flwd;
%let flwd = ;
%put FLWD: &flwd;
 
%macro forelastwd;
     data _null_;
          length havevar $9 havevar_sas 8;
          havevar = symget('load_day');
          havevar_sas = input(trim(havevar),date9.);

          do until (weekday(havevar_sas) in (2,3,4,5,6) );
                havevar_sas = intnx('day',havevar_sas,-1);
                call symput('flwd',havevar_sas);
                %put Vorletzter Werktag: &flwd;
          end;
     run;
%mend;
%forelastwd;

 

At the end &flwd is assigned NULL. How do i get this to work?

 

Thanks in advance

 

Noki

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

When you place your %put within the data step, it is executed by the macro engine before the data step runs. (typical macro language behaviour!)

data _null_;
length havevar $9 havevar_sas 8;
*havevar = symget('load_day');
havevar = '12may2016';
havevar_sas = input(trim(havevar),date9.);
do until (weekday(havevar_sas) in (2,3,4,5,6) );
  havevar_sas = intnx('day',havevar_sas,-1);
  call symput('flwd',havevar_sas);
end;
run;
%put Vorletzter Werktag: &flwd;

will give you this in the log:

16         data _null_;
17         length havevar $9 havevar_sas 8;
18         *havevar = symget('load_day');
19         havevar = '12may2016';
20         havevar_sas = input(trim(havevar),date9.);
21         do until (weekday(havevar_sas) in (2,3,4,5,6) );
22           havevar_sas = intnx('day',havevar_sas,-1);
23           call symput('flwd',havevar_sas);
24         end;
25         run;

NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
      23:22   
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      

26         %put Vorletzter Werktag: &flwd;
Vorletzter Werktag:        20585

View solution in original post

4 REPLIES 4
Kurt_Bremser
Super User

When you place your %put within the data step, it is executed by the macro engine before the data step runs. (typical macro language behaviour!)

data _null_;
length havevar $9 havevar_sas 8;
*havevar = symget('load_day');
havevar = '12may2016';
havevar_sas = input(trim(havevar),date9.);
do until (weekday(havevar_sas) in (2,3,4,5,6) );
  havevar_sas = intnx('day',havevar_sas,-1);
  call symput('flwd',havevar_sas);
end;
run;
%put Vorletzter Werktag: &flwd;

will give you this in the log:

16         data _null_;
17         length havevar $9 havevar_sas 8;
18         *havevar = symget('load_day');
19         havevar = '12may2016';
20         havevar_sas = input(trim(havevar),date9.);
21         do until (weekday(havevar_sas) in (2,3,4,5,6) );
22           havevar_sas = intnx('day',havevar_sas,-1);
23           call symput('flwd',havevar_sas);
24         end;
25         run;

NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
      23:22   
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      

26         %put Vorletzter Werktag: &flwd;
Vorletzter Werktag:        20585
Noki
Calcite | Level 5
Thanks a lot!
So programming was right, but the place was wrong.
You saved my day 🙂
Ksharp
Super User

Why not use WEEKDAY interval ?

 

52 data _null_;
53 havevar = '12may2016';
54 havevar_sas = input(trim(havevar),date9.);
55 havevar_sas = intnx('weekday',havevar_sas,-1);
56 put havevar_sas= ;
57 run;
 
havevar_sas=20585
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Whilst you have an answer to your problem, I would like to put some points in.  I don't see any reason given here why load_day should be a macro variable - it is numeric date data so text based macro variable is not a good storage medium for that data, or why this code given here is put in a macro at all.  Macro language is a method for generating Base SAS code, it doesn nothing else.  Base SAS code is there to process and manipulate data.  All that happens when Base SAS code is forced into Macro language is that the code becomes obfuscated.  Take your problem for instance, it is a simple task of checking if the week day of a date is a weekend, and if so returning Friday, otherwise the day.  You have compounded this simple problem by first putting a date into a text macro variable - thus you need additional code to process that back into a usable format.  Now look at the equivalent statement if your date is stored in a dataset in a strcuture which is designed to handle "data" elements:

data have;
  load_day="12May2016"d;
  last=ifn(weekday(load_day) in (1,7),6,weekday(load_day)-1);
run;

Simpler, doesn't require working out what is being done.  

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
  • 4 replies
  • 975 views
  • 1 like
  • 4 in conversation