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
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.
Yes, a simple construction like
%if %sysfunc(upcase("&myparameter.")) eq "FLAG" %then %do;
data whatever;
/*statements*/
run;
%end;
should accomplish what you want.
Thanks Art. I am giving this a shot and will let you know.
Paul
Hi Art,
Just curious, is there any reason why you didn't use macro function %upcase?
Regards,
Amir.
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.
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
Gosh, Peter, are you suggesting there may be room for improvement in some of the autocall macros provided by SAS?
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.
A good example of why you should only turn on SYMBOLGEN and MLOGIC as a last resort in debugging a macro.
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
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();
Does your macro parameter value have quotes? Or do you allow for either quoted or not quoted values?
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.