In the following codes an attempt is made to raise the abstraction level available to the sas programmer by providing list manipulation macros:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * List manipulation macros : | |
| * The first 9 macros are used for the manipulation of lists. | |
| */ | |
| /** | |
| * Everywhere in this code list will refer to space separated words stored in a macro variable | |
| * These have been used extensively in this program. | |
| * | |
| * eg usage of a list | |
| * %let MacroVariable_To_Store_List = ListElement1 ListElement2 ListElement3 ListElement4; | |
| * Then | |
| * %scan(&MacroVariable_To_Store_List, 3, %str( )) | |
| * will return ListElement3 | |
| */ | |
| /** | |
| * The macro returns the number of words in the list given as the parameter – VariableList | |
| */ | |
| %macro LengthOfList(VariableList); | |
| %let i = 1; | |
| %do %while(%scan(&VariableList, &i, %str( )) ne %str()); | |
| %let i = %eval(&i + 1); | |
| %end; | |
| %eval(&i – 1) | |
| %mend LengthOfList; | |
| /** | |
| * The macro returns a new list from a list (given as the first parameter- VariableList) | |
| * with one word deleted (which is the second parameter – VarToBeRemoved) | |
| */ | |
| %macro DeleteOneFromList(VariableList,VarToBeRemoved); | |
| %let i = 1; | |
| %do %while(%scan(&VariableList, &i, %str( )) ne %str()); | |
| %let var = %scan(&VariableList, &i, %str( )); | |
| %if %index(&var,&VarToBeRemoved) = 0 %then &var; | |
| %let i = %eval(&i + 1); | |
| %end; | |
| %mend DeleteOneFromList; | |
| /** | |
| * The macro returns a new list from a list (given as the first parameter – VariableList) with a | |
| * specified list of words deleted (which is the second parameter – ListOfVarsToBeRemoved) | |
| */ | |
| %macro DeleteFromList(VariableList,ListOfVarsToBeRemoved); | |
| %let outer = 1; | |
| %do %while(%scan(&ListOfVarsToBeRemoved, &outer, %str( )) ne %str()); | |
| %let TempList = ; | |
| %let varO = %scan(&ListOfVarsToBeRemoved, &outer, %str( )); | |
| %let inner = 1; | |
| %do %while(%scan(&VariableList, &inner, %str( )) ne %str()); | |
| %let varI = %scan(&VariableList, &inner, %str( )); | |
| %if &varO ne &varI | |
| %then %let TempList = &TempList &varI; | |
| %let inner = %eval(&inner + 1); | |
| %end; | |
| %let VariableList = &TempList; | |
| %let outer = %eval(&outer + 1); | |
| %end; | |
| &VariableList | |
| %mend DeleteFromList; | |
| /** | |
| * The macro checks whether a particular macro variable (given as the parameter Macrovar) already exists | |
| * or not | |
| */ | |
| %macro CheckExistenceOfMacroVar(Macrovar); | |
| %* Taken from the publicly available code sample by DeVenezia | |
| %* Richard A. DeVenezia 12/23/98; | |
| %* macrovar – name of macro variable to check for existence; | |
| %* emits | |
| %* 0 if macro variable is not found in SASHELP.VMACRO; | |
| %* 1 if macro variable is found in SASHELP.VMACRO; | |
| %* -1 if an error occurred; | |
| %* Note: if option NOTES and the macro variable is not found in | |
| %* SASHELP.VMACRO by the where clause of the open statement | |
| %* there will be a note in the log | |
| %* NOTE: No observations were selected from data set SASHELP.VMACRO. | |
| %* There is currently no way to circumvent this. | |
| %*; | |
| %local dsid; | |
| %let dsid = %sysfunc (open (SASHELP.VMACRO (where=(name=upcase("¯ovar") and scope ne "EXISTMV")))); | |
| %if &dsid %then %do; | |
| %sysfunc (attrn (&dsid, ANY)) | |
| %let dsid = %sysfunc (close (&dsid)); | |
| %end; | |
| %else %do; | |
| -1 | |
| %end; | |
| %mend CheckExistenceOfMacroVar; | |
| /** | |
| * From macrovariables – MacroVarsPrefix_1 … MacroVarsPrefix_n this macro returns a list which has | |
| * values stored in the individual macro variables. | |
| * It checks the existence of n-th macro variable and if it exists adds it to the list | |
| */ | |
| %macro CreateOneListFromMacroVars(MacroVarsPrefix); | |
| %let listab = ; | |
| %let i = 1; | |
| %do %while(%CheckExistenceOfMacroVar(&MacroVarsPrefix&i) = 1); | |
| %let listab = &listab &&&MacroVarsPrefix.&i; | |
| %if &i > 1000 | |
| %then %do; | |
| %put ERROR: In CreateOneListFromMacroVars Macro ; | |
| %goto exit; | |
| %end; | |
| %let i = %eval(&i + 1); | |
| %end; | |
| &listab | |
| %exit: | |
| %mend CreateOneListFromMacroVars; | |
| /** | |
| * (Same as above except that it stops at the value of n corresponding to the input parameter – UntilIndex. ) | |
| * From macrovariables – MacroVarsPrefix_1 … MacroVarsPrefix_UntilIndex this macro returns a | |
| * list which has values stored in the individual macro variables. | |
| */ | |
| %macro CreateOneListFromMacroVars2(MacroVarsPrefix, UntilIndex); | |
| %let listab = ; | |
| %let i = 1; | |
| %do %while(&i le &UntilIndex); | |
| %if %CheckExistenceOfMacroVar(&MacroVarsPrefix&i) = 1 | |
| %then %do; | |
| %let listab = &listab &&&MacroVarsPrefix.&i; | |
| %if &i > 1000 | |
| %then %do; | |
| %put ERROR: In CreateOneListFromMacroVars2 Macro ; | |
| %goto exit; | |
| %end; | |
| %end; | |
| %else %do; | |
| %put ERROR: In CreateOneListFromMacroVars2 Macro ; | |
| %put Atleast one MacroVariable from which list is to be created does not exist ; | |
| %goto exit; | |
| %end; | |
| %let i = %eval(&i + 1); | |
| %end; | |
| &listab | |
| %exit: | |
| %mend CreateOneListFromMacroVars2; | |
| /** | |
| * To each of the words in the input list (given as a parameter VariableList) it adds a prefix | |
| * eg if macro variable InputList has value – word1 word2 word3 | |
| * then %AddPrefixToVarsInList(&InputList, Prefix) | |
| * returns | |
| * Prefixword1 Prefixword2 Prefixword3 | |
| */ | |
| %macro AddPrefixToVarsInList(VariableList, Prefix); | |
| %let i = 1; | |
| %do %while(%scan(&VariableList, &i, %str( )) ne %str()); | |
| %let var = %scan(&VariableList, &i, %str( )); | |
| &Prefix&var | |
| %let i = %eval(&i + 1); | |
| %end; | |
| %mend AddPrefixToVarsInList; | |
| /** | |
| * Same as above except that it adds the second parameter as a suffix to each of the word in the inputlist | |
| */ | |
| %macro AddSuffixToVarsInList(VariableList, Suffix); | |
| %let si = 1; | |
| %do %while(%scan(&VariableList, &si, %str( )) ne %str()); | |
| %let var = %scan(&VariableList, &si, %str( )); | |
| &var&Suffix | |
| %let si = %eval(&si + 1); | |
| %end; | |
| %mend AddSuffixToVarsInList; | |
| %macro AddPrefixToVarsInList(PrefixVariableList, Prefix); | |
| %let PrefixIterator = 1; | |
| %do %while(%scan(&PrefixVariableList., &PrefixIterator., %str( )) ne %str()); | |
| %let var = %scan(&PrefixVariableList., &PrefixIterator., %str( )); | |
| &Prefix.&var. | |
| %let PrefixIterator = %eval(&PrefixIterator. + 1); | |
| %end; | |
| %mend AddPrefixToVarsInList; | |
| %macro AddSuffixToVarsInList(SuffixVariableList, Suffix); | |
| %let SuffixIterator = 1; | |
| %do %while(%scan(&SuffixVariableList., &SuffixIterator., %str( )) ne %str()); | |
| %let var = %scan(&SuffixVariableList., &SuffixIterator., %str( )); | |
| &var.&Suffix. | |
| %let SuffixIterator = %eval(&SuffixIterator. + 1); | |
| %end; | |
| %mend AddSuffixToVarsInList; | |
| /** | |
| * Combination of the two above, adds prefix and suffix to each of the words in the list in one step | |
| */ | |
| %macro AddPrefandSufToVarsInList(VariableList, Prefix, Suffix); | |
| %let si = 1; | |
| %do %while(%scan(&VariableList, &si, %str( )) ne %str()); | |
| %let var = %scan(&VariableList, &si, %str( )); | |
| &Prefix.&var.&Suffix | |
| %let si = %eval(&si + 1); | |
| %end; | |
| %mend AddPrefandSufToVarsInList; | |
| /*List manipulation macros End*/ | |