LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (January 1999, week 2)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:   Thu, 14 Jan 1999 10:28:26 -0500
Reply-To:   David D Kane <ddk@NUMERIC.COM>
Sender:   "SAS(r) Discussion" <SAS-L@UGA.CC.UGA.EDU>
From:   David D Kane <ddk@NUMERIC.COM>
Organization:   Numeric Investors L.P.
Subject:   Scoping variables one level up
Content-Type:   multipart/mixed;

Surely, someone has already solved this problem.

How does one force a macro variable to have a scope that is one level above the macro in which it is created but *not* global?

Consider a utility (attached at the end of this message) that creates an inderminate number of macro variables (var1, var2, etc) on the basis of the observations in a data set. I use this utility (ScanList) all the time (if someone has a better version, please post it). In order for the calling macro to uses var1, var2 . . ., I need to declare them as global.

The problem is that I work on big projects with other people. These projects might have a large macro, call it top, which would call my macro, call it middle1, which uses ScanList as well as Jones' macro, call it middle2, which also calls ScanList. But Jones and I may not know about each other and now the global variables (which we really want to be *local* to middle1 and middle2) can conflict with each other in top. This is a problem. How should we solve it? How do we "transfer" a macro variable created in ScanList to the calling macro without making that macro variable global?

/*******************************************************************************

* Program name: ScanList.sas * * Programmer: DDK * * Purpose: This small macro is intended to facilitate the easy creation of an * indeterminate number of macro variables. It takes five arguments: * * dataset is a flag indicating whether or not the variables are being passed * in in a dataset. TRUE means that they are. The default is FALSE. If * they are not in a data set then they must be in a string deliminated by * delim. * list is either a data set name (if dataset is TRUE) or it is a string * deliminated by delim, the default value for which is the pipe (|). The * presense of spaces is irrelevant in list. * delim is the deliminator used in list. The default value is pipe (|). * prefix is the base name of the macro variables to be created. * numName is the desired name for the number of macro variables created. * variable is the name of the variable in the dataset called list which has * the desired values for the macro variables. * * The macro creates variables of the form name1, name2, et cetera and places * the values in them. It also creates a variable, numName, with the number * of variables in the list. If the list is empty then no macro * variables will be created (I think). * * Date created: 9809 * *******************************************************************************/

%Macro ScanList( dataset = FALSE, list =, delim = |, prefix =, numName =, variable = );

/*******************************************************************************

* * The code is in two parts. First, for string input and second for a dataset. * I need to add a flag for checking whether the data set (or the list) is empty. * *******************************************************************************/

%if &numName eq %then %let numName = &prefix.num;

%local i howMany; %global &numName;

%if &dataset eq FALSE %then %do;

%let i = 1;

%do %while( %scan(&list, &i, |) ne ); %global &prefix&i; %let &prefix&i = %scan(&list, &i, |); %let i = %eval(&i + 1); %end;

%let &numName = %eval(&i - 1);

%end; %else %if &dataset eq TRUE %then %do;

data _NULL_; set &list end = last; if last then call symput('howMany', put(_N_, 8.)); run;

%do i = 1 %to &howMany; %global &prefix&i; %end;

data _NULL_; set &list; call symput(compress("&prefix"||put(_N_, 8.)), compress(&variable)); run;

%let &numName = &howMany;

%end;

%Mend ScanList;


[text/x-vcard]

begin: vcard fn: David Kane n: Kane;David org: Numeric Investors email;internet: ddk@numeric.com title: Statistician x-mozilla-cpt: ;0 x-mozilla-html: FALSE version: 2.1 end: vcard


Back to: Top of message | Previous page | Main SAS-L page