BookmarkSubscribeRSS Feed
JuanVte
Calcite | Level 5
Dear all,

I would like to learn how to create function style macros, i.e, macros which returns some value.

Could somebody recommend me any documentation.

I am using this kind of macros but sometimes my function doesn't work and I do not understand why.

For example:

%macro t1();
%if &t1>0 %then %do;
%let t1 = %eval(&t1+1);
%let t2 = 0;
%end;
%else %let t1 = 1;
&t1.
%mend;

%let t1=0;

%put %t1;
%put %t1;

IT WORKS BUT,

%macro maxcol(in,var);
local max;
proc sql noprint;
select max(&var) into :max
from ∈
quit;
&max.
%mend;

IT DOESN'T WORK.

Perhaps, I can't use non macro sentences in this kind of macros?

Thanks for your help!!
Juan Vte.
4 REPLIES 4
Andre
Obsidian | Level 7
Juan
this is working
you forget a % before local
but from a point of view of sas code generate
the value generated is outside any sas context
and rejected by the processor

[pre]
%macro maxcol(in,var);
%local max;
proc sql noprint;
select max(&var) into :max
from ∈
quit;
&max.
%mend;
%maxcol(sashelp.class,age)
[/pre]
JuanVte
Calcite | Level 5
Thank you Andre,

you are right.

But my real problem is about the second point, as you noted, this is outside any sas context!

For %t1 sas undertands perfectly what I want but not for %maxcol.

I would like to use this macro in sentences as for example:

%put %maxcol(sashelp.class,age);

or

if %maxcol(sashelp.class,age) > 0 then ...;

I can use %t1 but not with %maxcol in the above sentences. For that, I am thinking that I miss something else

What do you think?
Peter_C
Rhodochrosite | Level 12
there must be other ways to obtain the information you need from a "function-style" macro because between the 🙂 and 😉 of a statement using your "function-style" macro like [pre] 🙂 %maxcol( some.data_set ) 😉 [/pre] your macro cannot generate any semi-colons, and certainly not a step, without interrupting the statement in which %maxcol() is used.
Without generating semi-colons, there are ways to obtain for example:
* the NOBS of a SAS data set ~ from sashelp.vtable
* the maximum value of a variable in a dataset
If the macro must use open() fetch() and other functions, they must be called within a %sysfunc() "environment", not as plain base SAS syntax like proc contents data= &syslast out= _data_ noprint; run;

A function-style macro must generate only macro language statements, because everything else is the result returned by your macro.

You will need to recognise and understand the semi-colons that are part of your macro language statements and those which are generated.
The semi-colon of a %let statement is macro language.
In the macro statement [pre] %if &A eq &B %then %do ;
A
%end ;[/pre] no semi colons are generated. However this will generate four semi-colons[pre] %if not %sysfunc( exist( &ds )) %then %do ;
data _null_ ; file print ; put "no data in &ds"; run;
%end ;[/pre]

Hope this helps clarify what a "function-style" macro needs, and why your proposal could not work.

Good Luck

PeterC Message was edited by: Peter.C
JuanVte
Calcite | Level 5
Thanks for your clear comments Peter!

I'll think about how to do it without semicolons and I will come back to this post 😉

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 4 replies
  • 1605 views
  • 0 likes
  • 3 in conversation