04-04-2017 03:25 AM - edited 04-04-2017 03:26 AM
%macro db (ddmmyy); %if %substr(%right(&ddmmyy),5) = '0117' %then filename srcfile "path\201701\&ddmmyy..txt"; %if %substr(%right(&ddmmyy),5) = '0217' %then filename srcfile "path\201702\&ddmmyy..txt"; %else filename srcfile "path\ddmmyy..txt"; %mend;
I want to check the last 4 string of the paramater ddmmyy, and direct filename to a different file.
What's missing in the above statements?
04-04-2017 05:00 AM
As always, using Base SAS - which is the programming language - yields simpler, easier to maintain code:
data _null_; call execute(cat('filename srcfile "path\',right("&ddmmyy.",5),'\&ddmmyy..txt";'); run;
However, why do you have subfolders for date, and date as filename, that seems counter-productive. Put all the text files in one directory and use date in filename to identify them.
04-04-2017 11:54 PM
The best way to avoid overuse of SAS macro language is a developing an understanding of the functionality of the SAS language.
For example why not use the FILENAME() function instead of the FILENAME statement to solve this problem?
data _null_; length str $200 last4 $4 ; str = "&ddmmyy" ; last4 = substrn(str,length(str)-3); if last4 in ('0117' '0217') then str = cats('20',last4,'\',str); rc=filename('srcfile',cats('path','\',str,'.txt')); run;
04-05-2017 04:07 AM
As Tom has pointed out, knowing Base SAS as well as possible is the best route to minimising code. Back in the older versions of SAS there was a fair bit of functionality that was missing, and macro conviniently filled in there. However since V8 that has been a less and less need. Also programming has (should have) changed from using super intelligent next to impossible to read code due to system limitations, to the opposite, making code as simple to read as possible. Take for instance indentation, using single lines per command, code highlighting etc. all designed to make code as simple and easy to read as possible - think of it this way, you will one day have to maintain someone elses code so do you want simple or hard?
Now there are many ways to code, and many solutions to any problem. Some examples of where I look at simplifying:
Plan code, escpecially if it is re-useable code. Macro can be very usefull here, but does anyone actually write a specs document, a testing plan, a user manual? Coding is about 5% of any generalised tool, and yet the other 95% seems to not be done.
Avoid "Excel Thinking", this is transposed tables where anything goes.
Look at posts here, there are always very good things to learn, I still learn new things on here after 15years programming SAS which change the way I program.
Also, look at the way you delveop macros. Generally you will first write single code, then parameterise it. At the point you write the base code, minor changes can sometimes avoid the need to process further.
Hope that helps, its a bit in depth.
04-05-2017 11:07 PM
04-04-2017 06:38 AM
Three missing pieces.
%else is missing from the middle statement. The way it stands now, the only final results you get would match 0217 and none of the above.
& is missing in front of &ddmmyy in the last line.
The generated FILENAME statement is missing a semicolon. You would need to add it here:
And there are likely extra quotes. Macro language does not need quotes to compare two text strings. So the quotes around 0117 and 0217 should almost certainly be removed.
Finally, where you reference PATH, it would not resolve into anything. It will remain the four letters "path". That may be correct, or it may be incorrect, but that's what you will be getting.
04-04-2017 09:46 AM - edited 04-04-2017 09:48 AM
Why not simplify it? To find the last N characters just use length minus (N-1) as the starting location in %SUBSTR() call.
%macro db(ddmmyy); %local last4 fname; %let fname=path ; %if %length(&ddmmyy) > 3 %then %let last4=%substr(&ddmmyy,%length(&ddmmyy)-3); %if (&last4 = 0117) or (&last4 = 0217) %then %let fname=&fname\20&last4 ; filename srcfile "&fname\&ddmmyy..txt"; %mend;
Let's test it.
2747 options mprint; 2748 %db(0117) MPRINT(DB): filename srcfile "path\200117\0117.txt"; 2749 %db(xx) MPRINT(DB): filename srcfile "path\xx.txt"; 2750 %db(abced0217) MPRINT(DB): filename srcfile "path\200217\abced0217.txt";