DATA Step, Macro, Functions and more

Macro %str() and macro variable

Reply
New Contributor
Posts: 3

Macro %str() and macro variable

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:

%macro runrpt_all(nRun,dataset);

    %do z=1 %to &nRun;

        data _null_;

            set work.&dataset;

            if _n_ = &z then do;

                call symput('as_grp',trim(assess_Grp));

                call symput('lbl_1',trim(label_1));

                call symput('lbl_2',trim(label_2));

                call symput('lbl_3',trim(label_3));

                call symput('level',trim(lvl));

            end;

        run;

        %runrpt(&as_grp,%str(&lbl_1),%str(&lbl_2),&level,&lbl_3);

        dm "ODSRESULTS;CLEAR";dm 'CLEAR LOG;CLEAR OUTPUT;';

    %end;

    %put EXIT;

%mend runrpt_all;

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:

        data _null_;
            set work.&dataset;
            if _n_ = &z then do;
                call symput('as_grp',trim(assess_Grp));
                call symput('lbl_1',cats('%str(',label_1,')'));
                call symput('lbl_2',cats('%str(',label_2,')'));
                call symput('lbl_3',trim(label_3));
                call symput('level',trim(lvl));
            end;
        run;

        %runrpt(&as_grp,&lbl_1,&lbl_2,&level,&lbl_3);


Thanks for any help to answer this question

PROC Star
Posts: 1,231

Re: Macro %str() and macro variable

Hi,

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;


HTH

--Q.

New Contributor
Posts: 3

Re: Macro %str() and macro variable

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.

Philip

Super User
Super User
Posts: 6,500

Re: Macro %str() and macro variable

%SUPERQ() is probably the safest way to quote.

%runrpt(&as_grp,%superq(lbl_1),%superq(lbl_2),&level,%superq(lbl_3));

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.

%runrpt(&as_grp,"&lbl_1","&lbl_2",&level,"&lbl_3");

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 ;

data _null_;

  set work.&dataset;

   file code ;

  put '%runrpt'

    / '(' access_grp

    / ',' label_1 :quote.

    / ',' label_2 :quote.

    / ',' lvl

    / ',' label_3 :quote.

    / ');'

  ;

   if getoption('DMS')='DMS' then put

      "dm 'ODSRESULTS;CLEAR';"

    / "dm 'CLEAR LOG;CLEAR OUTPUT';"

  ;

run;

%inc code / source2 ;  

Ask a Question
Discussion stats
  • 3 replies
  • 529 views
  • 0 likes
  • 3 in conversation