BookmarkSubscribeRSS Feed
KevinViel
Pyrite | Level 9

I attempted to modularize several macros, one of which calls the REPORT procedure.  The default call using %DO loop in the COLUMN statement:

 

%do __i = 1 %to &num_of_cols. ;
   col&__i.
%end ;

A more complex call might intend the following:

( "Group 1"
  %do __i = 1 %to %eval( &num_of_cols. - 1 ) ;
        col__&i.
  %end ;
)
col__&i.

Since the first macro generates NUM_OF_COLS (dynamically), I want to pass that value from the calling program, through the first macro, and have it resolve in the second macro, which is called by the first.

 

I have tried a variety of %str(%%)do and %str(%%)str(%%) do to now avail.

 

I would appreciate any tips, corrections, or references.

 

Thank you,

 

Kevin

7 REPLIES 7
sbxkoenk
SAS Super FREQ

Hello,

 

I cannot entirely follow your reasoning, but you may be helped with the %GLOBAL Macro Statement.

%GLOBAL Macro Statement :

Creates macro variables that are available during the execution of an entire SAS session.

 

Syntax
%GLOBAL macro-variable(s);

 

Koen

Astounding
PROC Star

You'll have to supply more details about what is in the macros, and how the first macro calls the second.

 

When one macro calls another, its macro variables are automatically available.  So it's not possible to imagine where the problem lies.  

KevinViel
Pyrite | Level 9

Tom,

 

  That was my conclusion before posting.  I was providing the users some "free code" (free text) ability, but I will have to limit it.  Thank you for the example.  I wonder if  %sysfunc(dequote()) and %unquote() perform the same?  I will look it up in my free time, i.e. after I get out from under the wall of work and emails from being off a week.

 

Happy New Year!

 

Kevin

Tom
Super User Tom
Super User

%UNQUOTE() removes macro quoting.  DEQUOTE() removes actual quotes.  If you use %SYSFUNC() to call DEQUOTE() then the result has the macro quoting removed.

 

It will be easier for users to pass in values that contain macro triggers by using physical single quotes then figuring out the complex macro quoting rules/functions.

Quentin
Super User

Hi Kevin,

 

I'm not understanding your question, can you explain more?

 

It looks like you're trying to pass in the upper limit for the %do loop, right?

 

If you do something like:

 

%macro inner (limit=);
  %local i ;

  %put Before unquoting: &=limit ;
  %let limit=%unquote(&limit) ;
  %put After unquoting: &=limit ;

  %do i=1 %to &limit ;
    %put &=i ;
  %end ;

%mend inner ;

 

 

That will allow users to do a simple call like:

 

%inner(limit=3)

Users could also do more complex calls like:

 

 

%let num_of_cols=3 ;

%inner(limit=&num_of_cols)
%inner(limit=%nrstr(&num_of_cols))
%inner(limit=%nrstr(%eval(&num_of_cols -1)))

 

 

So in those last two calls, the user has used %NRSTR() to delay resolution of the macro reference to NUM_OF_COLS, until it has been %UNQUOTED inside the macro.

 

Depending on your use case, you might want to set the default value of LIMIT to be %nrstr(&num_of_cols). That would make the macro more tightly coupled to the calling environment, and less of a utility macro.

 

If the users are at an advanced  macro language level where they would *want* to pass a complex value like 

%eval( &num_of_cols. - 1 )

I think it's reasonable to teach them to add %nrstr() when necessary to delay resolution of macro references.

 

BASUG is hosting free webinars Next up: Mark Keintz presenting History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies on May 8. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
KevinViel
Pyrite | Level 9

Quentin,

 

  That would work on a more rigid macro:

 

               column %if %nrbquote(&report_column.) = %str()
                     %then
                        %do ;
                            section_order_1
                            row_order_1
                            row_1
                            %do __i = 1 %to &num_of_cols. ;
                               col&__i.
                            %end ;
                        %end ;
                      %else
                         %do ;
                             %unquote(&report_column.)
                         %end ;
                     ;

This current version does not allow column headers, for instance.  Consider that COL1 and COL2 should have one header and COL3 and COL4 another and COL5 none.

 

This was an issue when the macro was three deep: a macro called a macro that called this macro.  I have removed the embedding and the program calls the three macros in succession.

 

Interesting, at least for me, but I am on a timer 🙂

 

Thanks,

 

Kevin

Tom
Super User Tom
Super User

A word of advice.  Don't.  It is not worth the headache.

 

You cannot inject something like a %DO loop into an already compiled and running macro. But you could call some other macro that runs a %DO loop.

 

Add single quotes around the macro code you want to pass in and the use DEQUOTE() to remove them when you want it to run.

%macro some_function(a,b,c);
%put &=a &=b &=c;
%mend;
%macro mymacro(parm1,parm2,subroutine);
%put &=parm1 &=parm2;
%sysfunc(dequote(&subroutine));
%mend mymacro;

%mymacro(parm1=xx,parm2=yy,subroutine='%some_function(1,2,3)');

Result

730   %mymacro(parm1=xx,parm2=yy,subroutine='%some_function(1,2,3)');
PARM1=xx PARM2=yy
A=1 B=2 C=3

 

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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