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

Hello everyone.  I have a macro which needs to take an input (file name), and another input (time). 

So the macro and call could look like this (silly example).

%macro mymacro(fileinput=,timewait=);

data yay;

infile "&fileinput.";

input variable1;

run;

data _null_;

var1=sleep(&timewait.);

run;

%mend mymacro;

%mymacro;

%mymacro(c:\mydirectory\Filenamefilename(date1.csv, 1);

The problem is that SAS can't run this macro correctly because it recognizes the "(" in the first paramater as a ( function definition.   How would one get around this problem?  I want users to be able to put in any file name they want, but this one (and several others) cause problems at execution time.

The only thing i've been able to do so far is to make the first input a macro variable itself, and then to wrap it's call inside a %Bquote() function.  Aka my "solution" is

%let var1=c:\mydirectory\Filenamefilename(date1.csv;

%mymacro(%bquote(&var1.), 1);

I don't consider this a solution really, does anyone have any idea of how to solve this problem without first having to define a macro var and using %Bquote()?

Thanks!

1 ACCEPTED SOLUTION

Accepted Solutions
RW9
Diamond | Level 26 RW9
Diamond | Level 26

I would agree with all the previous posts here.  I would question firstly why people are using brackets in a filename, not good practice.  Secondly, I would avoid passing paths and what not into a macro at all.  There are many ways to approach this problem.  My initial thought is to ask then to assign a fileref *before* calling your macro.  They can do this anyway they like, and means the checking (i.e. existence) is done on their end rather than in your macro.  In your example there is no error checking for invalid parameter, missing file etc. Do you really want to accept responsibility for checking every possible permutation, considering its obvious that unbalanced brackets appears already?  If you go with the fileref, then you only need to check that that has been created.

Another alternative, is to put your parameters in a dataset.  You then have the full functionality of dataset operation, your macro could check the existence of the paramter dataset, then have a datastep which checks the contents, then generates the code from that.

I am sure your Functional Design Specification (following SLDC) would cover such things as how to get parameters in/out and what testing needs to be done within this library macro?  If its not a library macro, why bother with the macro at all, just call execute the statements anyways.

Not entirely sure why the wait is there.  This would indicate to me that you intend to pass an Excel file into the macro, open the DDE system and then read data in.  My suggestion, don't.  DDE is old, and my not be supported, plus only has functionality from years ago.  There are better ways  to get data into SAS.

View solution in original post

5 REPLIES 5
jakarman
Barite | Level 11

You are needing those quotes at the filename. is it acceptable to instruct the users to code it with those quotes.
the syspbuff is the only way that gives you full control on what is coded by your users. The disadvantage is having a lot of work to be done.

SAS(R) 9.2 Macro Language: Reference   

---->-- ja karman --<-----
Quentin
Super User

So the problem is that users have a file name with an unmatched parenthesis in it?  Ugh.  : )

I think Jaap is right that asking users to pass the filename in quotes should work.  (As long as you don't have file names with quotes in them… )

If users of your macro are SAS programmers, then I would think fair to require them to understand macro quoting if they want to use your macro and are silly enough to name their files in such an odd way, so that they could come up with something like below, which should work (?):

  %mymacro(fileinput=c:\mydirectory\Filenamefilename%str(%()date1.csv, timewait=1)

If your users are not SAS programmers, then hopefully they are passing the file name to some stored process (or whatever) as a macro variable, in which case your idea of using %BQUOTE or %SUPERQ should suffice.

BASUG is hosting free webinars Next up: Jane Eslinger presenting PROC REPORT and the ODS EXCEL destination on Mar 27 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Tom
Super User Tom
Super User

There are really two problems here.

1) Is how to call the macro with the unbalanced value.

You could use macro quoting such as

%mymacro(%str(c:\mydirectory\Filenamefilename%(date1.csv), 1);

Or you could just use actual quotes such as

%mymacro('c:\mydirectory\Filenamefilename(date1.csv', 1);

2) How to deal with the value in the macro.

For physical filenames it is useful to use the QUOTE() function so you can properly handle filenames that might include double quote characters.

You can also use the DEQUOTE() function to remove outer quotes that user might have provided. Note that if the value is not quoted then DEQUOTE() does nothing.


infile %sysfunc(quote(%qsysfunc(dequote(&fileinput)))) ;

RW9
Diamond | Level 26 RW9
Diamond | Level 26

I would agree with all the previous posts here.  I would question firstly why people are using brackets in a filename, not good practice.  Secondly, I would avoid passing paths and what not into a macro at all.  There are many ways to approach this problem.  My initial thought is to ask then to assign a fileref *before* calling your macro.  They can do this anyway they like, and means the checking (i.e. existence) is done on their end rather than in your macro.  In your example there is no error checking for invalid parameter, missing file etc. Do you really want to accept responsibility for checking every possible permutation, considering its obvious that unbalanced brackets appears already?  If you go with the fileref, then you only need to check that that has been created.

Another alternative, is to put your parameters in a dataset.  You then have the full functionality of dataset operation, your macro could check the existence of the paramter dataset, then have a datastep which checks the contents, then generates the code from that.

I am sure your Functional Design Specification (following SLDC) would cover such things as how to get parameters in/out and what testing needs to be done within this library macro?  If its not a library macro, why bother with the macro at all, just call execute the statements anyways.

Not entirely sure why the wait is there.  This would indicate to me that you intend to pass an Excel file into the macro, open the DDE system and then read data in.  My suggestion, don't.  DDE is old, and my not be supported, plus only has functionality from years ago.  There are better ways  to get data into SAS.

Anotherdream
Quartz | Level 8

Hey everyone.  Your assumptions are correct, we have files with "(" in them.    If you think that's bad, you should see some of the other file names..... If it can be put into a file name, it HAS been put into the files we receive.

Tom, your asnwer is exactly what I was looking for.  I wasn't aware you could simply use the %str() function around the filename.  I wil instruct that use in the explanation of the macro as it stands now.

Master

Fyi: The wait is just there for demo purposes. I just wanted to put another paramater into the macro so people could try to call it to see what happens with the unbalanced "(" and I couldn't think of anything easier than a wait.  I've actually never used DDE before.  I NEVER EVER read in Excel files in any of my code.  Honestly I feel like reading in data from Excel is a mistake (just my opinion).

Thanks for your help!

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
  • 5 replies
  • 2132 views
  • 4 likes
  • 5 in conversation