From: xlr82sas on
Hi SAS-Lers,

For a cleaner version see

/* T003120 MULTIPLE RANDOM? SETS OF FIXED SIZE FROM A GIVEN POPULATION
*/
http://homepage.mac.com/magdelina/.Public/utl.html
utl_tipweb.txt

Suppose you want to create a different static datastep variable tied
to each
macro call. A static variable is a different variable that is static
with respect to
each macro call. Also you want the static variable to disappear when
the datastep completes.

Here is the problem. I realize there are other ways solve this
problem,
but the purpose is to demonstrate static variables that are
tied to macro calls. Actually static variables are variables that
retain there value for each call to a subroutine call(out of scope but
not necessarily global). I also realize that macro code is really not
a subroutine, but it sure looks like a virtual subroutine.

You have a list of 30 random rumbers. And you want to select
3 samples of exactly 10,13 and 21 observations

data rnd030;
input rnd @@;
cards;
0.577 0.749 0.698 0.419 0.186 0.692
0.411 0.751 0.341 0.902 0.039 0.931
0.826 0.347 0.478 0.681 0.916 0.007
0.681 0.887 0.759 0.347 0.022 0.715
0.894 0.774 0.837 0.020 0.786 0.827
;run;


here is the solution

Note sysindex is incremented each time the macro is called so a
differerent
static variable will be defined for each call. Since the singe array
entry is temporary
it will disappear when the datastep complets.

%macro utl_fixrnd (obs,need,flag);
do;
array accum&sysindex[1] _temporary_ (0);
accum&sysindex(1) + &need;
if accum&sysindex(1) >= &obs then do;
accum&sysindex(1) = accum&sysindex(1) - &obs;
&flag=1;
end;
else &flag=0;
drop &flag;
end;
%mend utl_fixrnd;

data f10 f13 f21;
set rnd030;
%utl_fixrnd(30,10,f10); if f10 then output f10;
%utl_fixrnd(30,13,f13); if f13 then output f13;
%utl_fixrnd(30,21,f21); if f21 then output f21;
run;

The data set WORK.F10 has 10 observations
The data set WORK.F13 has 13 observations
The data set WORK.F21 has 21 observations


Each time the macro is called it creates a
different
temporary accumulator
variable.
The temporary variable is then incremented by 10, 13 and 21
this
will go on until the accumulator is greater or equal
to
the number of obs in the dataset at which
point
the accumulator will then reset and we start over .