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 😉

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
  • 4 replies
  • 899 views
  • 0 likes
  • 3 in conversation