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

Hi

I used macros all the time and always come across an issue--is it possible to use certain steps in a macro situationally? That is, depending on the value of one of the incoming parameters, process certain parts of the overall macro? For example, if the second parameter = "flag", then the "newValue" data step will be processed, otherwise it will be bypassed?

Paul

1 ACCEPTED SOLUTION

Accepted Solutions
art297
Opal | Level 21

: Why?  Good question!

My usual answer would be that I'm a psychologist, not a programmer.

However, the real answer was because I copied and pasted from an old macro I had handy and didn't even notice.  Interestingly, no one complained about the inclusion of quotes.  Yes, the following would have sufficed:

%if %upcase(&myparaneter)=FLAG %then

regardless, both will do what Paul wanted to accomplish.

View solution in original post

10 REPLIES 10
art297
Opal | Level 21

Yes, a simple construction like

%if %sysfunc(upcase("&myparameter.")) eq "FLAG" %then %do;

  data whatever;

    /*statements*/

  run;

%end;

should accomplish what you want.

Paul_NYS
Obsidian | Level 7

Thanks Art. I am giving this a shot and will let you know.

Paul

Amir
PROC Star

Hi Art,

Just curious, is there any reason why you didn't use macro function %upcase?

Regards,

Amir.

art297
Opal | Level 21

: Why?  Good question!

My usual answer would be that I'm a psychologist, not a programmer.

However, the real answer was because I copied and pasted from an old macro I had handy and didn't even notice.  Interestingly, no one complained about the inclusion of quotes.  Yes, the following would have sufficed:

%if %upcase(&myparaneter)=FLAG %then

regardless, both will do what Paul wanted to accomplish.

Peter_C
Rhodochrosite | Level 12

Hi Art

your choice to use %sysfunc() around upcase() is an interesting area.

Before sysfunc() became available, I had to debug a macro application which used the innocent-looking %LEFT().

I am now very happy to avoid that by adopting your approach %SYSFUNC(LEFT()).

These (%left and %upcase) may seem similar string handl;ing functions, but the macro language %UPCASE() is in fact a pre-compiled function, unlike %LEFT().

What folllows is a full debugging log comparing the noise level (lines in the saslog imply some activity) of %sysfunc(LEFT()) and %LEFT

First prepare a macro variable with leading blanks

%let test_str = %str(  123 abc x) ;

now switch on the macro diagnostics and now

and

option mprint mprintnest mlogic mlogicnest symbolgen ;

Here is activity of your way %put %sysfunc(left( &test_str ) ) ;

220  %put %sysfunc( left( &test_str )) ;

SYMBOLGEN:  Macro variable TEST_STR resolves to   123 abc x

SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.

123 abc x

and what follows are the lines from invoking classic SAS macro %put %left( &test_str );

There seems to be a lot going on!!

221  %put %left( &test_str );

MLOGIC(LEFT):  Beginning execution.

MLOGIC(LEFT):  This macro was compiled from the autocall file C:\Program Files\SASHome2\SASFoundation\9.4\core\sasmacro\left.sas

SYMBOLGEN:  Macro variable TEST_STR resolves to   123 abc x

SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.

MLOGIC(LEFT):  Parameter TEXT has value _  123 abc x_

MLOGIC(LEFT):  %LOCAL I

SYMBOLGEN:  Macro variable TEXT resolves to   123 abc x

SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.

MLOGIC(LEFT):  %IF condition %length(&text)=0 is FALSE

MLOGIC(LEFT):  %LET (variable name is I)

MLOGIC(LEFT.VERIFY):  Beginning execution.

MLOGIC(LEFT.VERIFY):  This macro was compiled from the autocall file C:\Program Files\SASHome2\SASFoundation\9.4\core\sasmacro\verify.sas

SYMBOLGEN:  Macro variable TEXT resolves to   123 abc x

SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.

MLOGIC(LEFT.VERIFY):  Parameter TEXT has value _  123 abc x_

MLOGIC(LEFT.VERIFY):  Parameter TARGET has value _ _

MLOGIC(LEFT.VERIFY):  %LOCAL I

SYMBOLGEN:  Macro variable TEXT resolves to   123 abc x

SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.

SYMBOLGEN:  Macro variable TARGET resolves to

SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.

MLOGIC(LEFT.VERIFY):  %IF condition %length(&text)=0 OR %length(&target)=0 is FALSE

SYMBOLGEN:  Macro variable TEXT resolves to   123 abc x

SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.

MLOGIC(LEFT.VERIFY):  %DO loop beginning; index variable I; start value is 1; stop value is 11; by value is 1.

SYMBOLGEN:  Macro variable TARGET resolves to

SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.

SYMBOLGEN:  Macro variable TEXT resolves to   123 abc x

SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.

SYMBOLGEN:  Macro variable I resolves to 1

MLOGIC(LEFT.VERIFY):  %IF condition NOT %index(&target,%qsubstr(&text,&i,1)) is FALSE

MLOGIC(LEFT.VERIFY):  %DO loop index variable I is now 2; loop will iterate again.

SYMBOLGEN:  Macro variable TARGET resolves to

SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.

SYMBOLGEN:  Macro variable TEXT resolves to   123 abc x

SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.

SYMBOLGEN: Macro variable I resolves to 2

MLOGIC(LEFT.VERIFY):  %IF condition NOT %index(&target,%qsubstr(&text,&i,1)) is FALSE

MLOGIC(LEFT.VERIFY):  %DO loop index variable I is now 3; loop will iterate again.

SYMBOLGEN:  Macro variable TARGET resolves to

SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.

SYMBOLGEN:  Macro variable TEXT resolves to   123 abc x

SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.

SYMBOLGEN:  Macro variable I resolves to 3

MLOGIC(LEFT.VERIFY):  %IF condition NOT %index(&target,%qsubstr(&text,&i,1)) is TRUE

MLOGIC(LEFT.VERIFY):  %GOTO VERFND (label resolves to VERFND).

SYMBOLGEN:  Macro variable I resolves to 3

SYMBOLGEN:  Macro variable TEXT resolves to   123 abc x

SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.

MLOGIC(LEFT.VERIFY):  %IF condition &i>%length(&text) is FALSE

SYMBOLGEN: Macro variable I resolves to 3

MLOGIC(LEFT.VERIFY):  Ending execution.

SYMBOLGEN:  Macro variable I resolves to 3

MLOGIC(LEFT):  %IF condition &i is TRUE

SYMBOLGEN:  Macro variable TEXT resolves to   123 abc x

SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.

SYMBOLGEN:  Macro variable I resolves to 3

MLOGIC(LEFT):  Ending execution.

123 abc x

Quentin
Super User

Gosh, Peter, are you suggesting there may be room for improvement in some of the autocall macros provided by SAS? Smiley Happy

I was lucky to take a macro course early in my career from Ian Whitlock.  He was kind enough to point out the difference between true pre-compiled macro functions (%UPCASE) and autocall macros doing the work of a function (%LOWCASE).  I noticed the docs differentiate these as well.  And most importantly, he encouraged us to peruse the source code of the autocall macros from SAS, and consider which stylistic approaches we might or might not want to adopt.

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

A good example of why you should only turn on SYMBOLGEN and MLOGIC as a last resort in debugging a macro.

Peter_C
Rhodochrosite | Level 12

thank you Tom

I agree for development of code, use minimum diagnostics.

  

It was in debugging a production problem without these diagnostics that I decided they have their place at that stage, especially mautolocdisplay and source2. In that situation it is difficult to re-run, after adding these options.

The %LEFT diagnostics example posted earlier was a bit "overkill", but points out how much might be "going on under the covers" of a macro. In that case the %verify() macro that is called by %left(), is designed to support more than %left() needs.

regards

Peter

Tom
Super User Tom
Super User

Yes.  That is one of the main reasons for creating a macro rather than just running a saved program.  There are a number of conditional statements in macro language.

%IF ... %THEN ... %ELSE

%DO;

%DO var=... %TO ... ;

%DO %WHILE();

%DO %UNTIL();

data_null__
Jade | Level 19

Does your macro parameter value have quotes?  Or do you allow for either quoted or not quoted values?

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
  • 10 replies
  • 1344 views
  • 2 likes
  • 7 in conversation