07-10-2013 12:12 PM
This is more of a question about the general understanding of how SAS processes procedures as I did develop a work around to this problem.
Here is the code below:
%do z=1 %to &nRun;
if _n_ = &z then do;
dm "ODSRESULTS;CLEAR";dm 'CLEAR LOG;CLEAR OUTPUT;';
Here is the situation. The code above was created in order to automate a process to run the macro "%runrpt" instead of having many "%runrpt" macro statements and adjusting them each program run. Within the dataset, Label_1 (&lbl_1) and Label_2 (&lbl_2) has instances of commas in their data. The "%runrpt" macro takes 4 variables in, so the commas would pose an issue. In order to resolve that case, the manual method used the %str() macro to encapsulate the manually inputted string that contained commas. So I decided to replicate the same method, hence why you see %str(&lbl_1) and %str(&lbl_2). However, doing that produced the very error I was trying to avoid; detection of too many parameters passed in.
So my question is, how does SAS process a %str() statement with a macro-variable inside. Again, under the manual method of placing %str(string,with,commas), the macro will run fine. Once I switch it to using a macro variable, I get the error regarding too many parameters detected.
My work-around is as follows:
if _n_ = &z then do;
Thanks for any help to answer this question
07-10-2013 12:43 PM
If you want to quote the resolved value of a macro variable, you need to use another quoting function, either %bquote() or %superq() rather than %str().
On a related note, I suggest you look at CALL EXECUTE for this sort of data driven macro call approach. With it, you can have a dataset of macro parameter values (as you have), and then in a data step, call a macro once for every record, passing in the values. So you can do what you've done with less overhead.
Something like (untested):
data _null_; set work.&dataset; call execute ( '%nrstr(' || '%RunRpt' || '(' || ' assess_Grp ' || ',label_1 ' || ',label_2 ' || ',label_3 ' || ' )' || ')' ); run;
07-10-2013 02:10 PM
Thank you Quentin for your response. There are too many macro functions to keep track of and I had just forgotten that one.
Regarding your suggestion to use call execute. I did think of using that as I have implemented that strategy in other portions of the project I am working on. The quick method that came out of my head was what you see. I may convert the code later however the overhead concerns are not critical to this program at the moment.
Thank you again for the help.
07-10-2013 03:18 PM
%SUPERQ() is probably the safest way to quote.
Other things to consider is to modify the macro so that parameters where the values might have commas or other special characters are delivered with quotes around them.
As far as a quick method for generating a lot of macro calls from a data set I find that using SAS to write the code to a file is the easiest to work with. You can eyeball the file to make sure the code looks right. Open it and submit the first few lines. Or even take it and embed it in another program.
filename code temp ;
file code ;
/ '(' access_grp
/ ',' label_1 :quote.
/ ',' label_2 :quote.
/ ',' lvl
/ ',' label_3 :quote.
if getoption('DMS')='DMS' then put
/ "dm 'CLEAR LOG;CLEAR OUTPUT';"
%inc code / source2 ;