BookmarkSubscribeRSS Feed
afiqcjohari
Quartz | Level 8
%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?

8 REPLIES 8
RW9
Diamond | Level 26 RW9
Diamond | Level 26

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.  

afiqcjohari
Quartz | Level 8
I keep getting this advice. Could you give suggestions on any ressources I can use so that I can minimize the use of macro?
Tom
Super User Tom
Super User

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;
RW9
Diamond | Level 26 RW9
Diamond | Level 26

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.

afiqcjohari
Quartz | Level 8
I've pretty much said farewell to Excel for quite sometime but unfortunately, the current employer uses Excel pretty extensively. I'm pretty much bounded by the analytical culture here.
afiqcjohari
Quartz | Level 8
As for the directory, I agree but unfortunately the owner has created the folder that way. Nevertheless the structure can be useful in other tasks.
Astounding
PROC Star

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:

 

;

%mend;

 

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.

Tom
Super User Tom
Super User

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";

 

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 8 replies
  • 7460 views
  • 7 likes
  • 4 in conversation