I have a SAS script that reads in a CSV file and stores it in a SAS data set:
LIBNAME IN '\\path\Data';
FILENAME CSV '\\path\Data\DT.csv';
DATA IN.DT;
INFILE CSV DLM=',' DSD FIRSTOBS=1;
INPUT KEY VALUE1 VALUE2;
RUN;
I want to change it such that instead of expecting the input to be named DT.csv, it would accept an input named DT-2016-03-03-TEST.csv, or whatever the current date is. In other words, I need to use a dynamic value in my FILENAME statement.
Here is what I have so far:
%LET curday = %SYSFUNC(day("&sysdate"d));
%LET curmonth = %SYSFUNC(month("&sysdate"d));
%LET curyear = %SYSFUNC(year("&sysdate"d));
%PUT %SYSFUNC(PUTN(&curday, z2.));
FILENAME CSV "\\path\Data\DT-&curyear-&curmonth-&curday-TEST.csv";
But the string it generates is like Data\DT-2016-3-3-TEST.csv rather than Data\DT-2016-03-03-TEST.csv
In other words, the trailing zeros are not there. What am I doing incorrectly?
You'll need to use either a macro variable or a big group of macro functions (whichever you'd like). We'll go with creating macro variables for readability purposes. Based upon what you've said, we know a few things about the pattern:
DT-yyyy-mm-dd format.csvTwo of these are static values, and one needs to be dynamic in a specific format. Let's get crackin'.
Start off by storing the path in its own macro variable. This makes the code more generalizable to other applications (i.e. you can copy/paste old code for new programs! It's good to be lazy in the programming world).
%let path = \\path\data;
Next, let's build our dynamic pattern using a %let statement. We know it starts with DT-:
___________________________________________
%let file = DT-
___________________________________________
We can now cross #1 off the list! Let's knock out #2.
Two functions will help us get this in the order that we want:
%sysfunc()today()We'll encapsulate today() with %sysfunc(). %sysfunc() lets us run most non-macro-language SAS functions, and also has the added benefit of returning the value in a format that you desire using an additional argument. This is really helpful for us here.
So, let's grab today's date as a numeric SAS date, then convert it to yymmddx10 format, where x is some delimiter keyword. We'll use yymmddd10. - that is, a format that specifies yyyy-mm-dd. The extra d means dash.
___________________________________________
%let file = DT-%sysfunc(today(), yymmddd10.)
___________________________________________
2 is now out of the way. Hard part's over! All we need to do is append .csv to it, and we'll be all set.
___________________________________________
%let file = DT-%sysfunc(today(), yymmddd10.).csv;
___________________________________________
You can confirm the macro variable file's value with a %put statement:
%put NOTE: This is my filename: &file;
You should see in green text in the log NOTE: This is my filename: DT-2016-03-03.csv
Now, we'll just put it all together:
%let path = \\path\data;
%let file = DT-%sysfunc(today(), yymmddd10.).csv;
libname IN "&path";
filename CSV "&path\&file";
data in.DT;
infile csv dlm=',' dsd firstobs=1;
input key value1 value2;
run;
You've now got a dynamic way to read in these CSVs, and you can adapt this code elsewhere. Awesomesauce. I think you've earned yourself a celebratory coffee, and maybe a biscotti or two; don't go too crazy.
Stu's answer is absolutely correct. For the tl;dr version.
%put echos stuff to the log. All you are doing is "putting" the result of %SYSFUNC(PUTN(&curday, z2.)) to the log. You are not updating the value in &curday.
Try
%LET curday = %SYSFUNC(PUTN(&curday, z2.));
Do that for the other curmonth, too.
Take the time and read Stu's answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With