Hello,
here's what I am trying to accomplish:
%let annee=2018;
%let mois=02;
%macro bs(mois);
%if &mois = 01 %then %let dobs='31jan'&annee;
%if &mois = 02 %then %let dobs='28feb'&annee;
%if &mois = 03 %then %let dobs='31mar'&annee;
%if &mois = 04 %then %let dobs='30apr'&annee;
%if &mois = 05 %then %let dobs='31may'&annee;
%if &mois = 06 %then %let dobs='30jun'&annee;
%if &mois = 07 %then %let dobs='31jul'&annee;
%if &mois = 08 %then %let dobs='31aug'&annee;
%if &mois = 09 %then %let dobs='30sep'&annee;
%if &mois = 10 %then %let dobs='31oct'&annee;
%if &mois = 11 %then %let dobs='30nov'&annee;
%if &mois = 12 %then %let dobs='31dec'&annee;
%mend bs;
%put &dobs;
So basically, dobs should have the value "30feb2018"
Macro is always and only text. You cannot apply datastep formats to something which does not exist in datastep language. This is one of the reasons i highly recommend you use Base SAS programming for data manipulation, and leave macro requirements out of it.
%let annee=2018; %let mois=02; data _null_; call symputx('dobs', put(intnx('day',mdy(&mois,1,&annee),0)-1,date9.)); run; %put &dobs;
%let annee=2018;
%let mois=02;
%put &mois;
%macro bs;
%if &mois = 02 %then %let dobs="28feb&annee";
%put &dobs;
%mend bs;
%bs
Why not:
%let annee=2018; %let mois=02; data _null_; call symputx('dobs', intnx('day',mdy(&mois.,&annee,1),'beginning')); run;
Its amazing what you can do with Base SAS - which is the actual programming language.
Thanks!
I tried the following:
%let annee=2018;
%let mois=02;
data _null_;
call symputx('dobs', intnx('day',mdy(&mois,1,&annee),0)-1);
format &dobs date9.;
run;
%put &dobs;
Output:
21215
How can I convert this to 28FEB2018
@pkopersk wrote:
Thanks!
I tried the following:
%let annee=2018;
%let mois=02;
data _null_;
call symputx('dobs', intnx('day',mdy(&mois,1,&annee),0)-1);
format &dobs date9.;
run;
%put &dobs;
Output:
21215
How can I convert this to 28FEB2018
The question is, what for? If you need it for comparison or calculation purposes, the raw numerical value is ideal. If you need it for display anywhere, format it there. Note that the best (because standardized) format for a date is e8601da. (which is equivalent to yymmddd10.), as it conforms to the ISO 8601 standard.
@pkopersk wrote:
I have a huge table where each column has the name following this format:
DDMMMYYYY where MMM is a string representing the 3 first letters of each
month.
I want to have to replace the first two variables %annee and %mois and run
the program.
The macro variable %dobs has to dynamically adapt to my input and has to be
a macro variable because it is used everywhere in the program.
I see at least two violations of sound programming practice here:
Edit: added the missing "severe".
Yes, what we have here is a classic case of bad data modelling using Excel thinking. You have put "data" as column names, and that data is an abstract form in itself. A simple normalisation will remove this issue completely:
From:
id 01jan2018 02Jan2018 03Jan2018
1 abc def ghi
To:
id date res
1 01jan2018 abc
1 02jan2018 def
1 03jan2018 ghi
...
Do note that you can always transpose that data up when you have finished your programming so the end product looks like the starting product, but your programming internally will be much much easier.
Macro is always and only text. You cannot apply datastep formats to something which does not exist in datastep language. This is one of the reasons i highly recommend you use Base SAS programming for data manipulation, and leave macro requirements out of it.
%let annee=2018; %let mois=02; data _null_; call symputx('dobs', put(intnx('day',mdy(&mois,1,&annee),0)-1,date9.)); run; %put &dobs;
It looks like you want the last day of the month. This will depend on the year, what about leap years? Your code doesn't account for that.
It's better to use INTNX() to get the value. You need a starting date for the INTNX function and then an increment but we don't know what you're starting with.
Here's some examples of working with dates.
https://communities.sas.com/t5/SAS-Communities-Library/Macro-Variables-of-Date-and-Time/ta-p/475194
If you explain what you want, we can likely help you with a more efficient solution.
@pkopersk wrote:
Hello,
here's what I am trying to accomplish:
%let annee=2018;
%let mois=02;
%macro bs(mois);
%if &mois = 01 %then %let dobs='31jan'&annee;
%if &mois = 02 %then %let dobs='28feb'&annee;
%if &mois = 03 %then %let dobs='31mar'&annee;
%if &mois = 04 %then %let dobs='30apr'&annee;
%if &mois = 05 %then %let dobs='31may'&annee;
%if &mois = 06 %then %let dobs='30jun'&annee;
%if &mois = 07 %then %let dobs='31jul'&annee;
%if &mois = 08 %then %let dobs='31aug'&annee;
%if &mois = 09 %then %let dobs='30sep'&annee;
%if &mois = 10 %then %let dobs='31oct'&annee;
%if &mois = 11 %then %let dobs='30nov'&annee;
%if &mois = 12 %then %let dobs='31dec'&annee;
%mend bs;
%put &dobs;
So basically, dobs should have the value "30feb2018"
I don't think you can get 30feb2018, perhaps 28feb2018. As others have pointed out, sometimes February has 29 days instead of 28.
But all that aside, you have two choices. You can simply remove all the quotes from the macro if you want:
28feb2018
Or, you can change them to double quotes and move the closing quote if you want:
"28feb2018"
For that, change the desired expressions:
... %then let dobs="28feb&annee";
If you use SAS date values (unformatted) in your macro variables, you can use date functions and formats for all this.
Use functions.
You don't really need a macro since it is just a one liner. But if you do make a macro then make it more useful by using parameters and creating a "function" style macro.
%let annee=2018;
%let mois=02;
%macro bs(year,month);
%sysfunc(intnx(month,%sysfunc(mdy(&month,1,&year)),0,e),date9)
%mend bs ;
%let dobs=%bs(&annee,&mois);
Results:
589 %let dobs=%bs(&annee,&mois); 590 %put &=annee &=mois &=dobs ; ANNEE=2018 MOIS=02 DOBS=28FEB2018
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.