Aug 25, 2013

SAS macro to split a macro variables values to multiple macro variables values and also get the split count into another variable

And also there could be other instances where you need to do the opposite i.e. split a macro variable values list into individual pieces and get them into a series of macro variable values. One can use the below macro for such a requirement.


/**************************************************************************************************************
* Macro_Name:   split_macrovalue                                                                       
*
* Purpose: this macro is used to split a macro and return series of macro variables
*         
*                                                                                                             
* Usage: %split_macrovalue(macvar,prefix,splitcnt,dlm=' ');
*
* Input_parameters: macvar - input macro var
*                   prefix - prefix of the macro vars to be created in sequence order...
*                   splitcnt - name of the macro vars to store the length of the macro variable
*                   dlm=     - delimiter in the string (default is comma i.e. ,)
*                                                                                                             
* Outputs:  None.                                                                                              
*                                                                                                             
* Returns:  None  
*
* Example:
*                                                     %let str1=he she me to 3 "some";
*                                                     %SplitMacroValue(str1,pre,strcnt,dlm=' ');
*                                                    
*                                                     %put pre1=&pre1 pre2=&pre2 pre3=&pre3 pre4=&pre4 pre5=&pre5 pre6=&pre6 ;
*                                                     %put strcnt=&strcnt;
*                                                                                                             
* Modules_called: None
*
* Maintenance_History:                                                                                       
*-------------------------------------------------------------------------------------------------------------*
*  Date:      |   Who:        |  Description:                                                                 *
*-------------------------------------------------------------------------------------------------------------*
* 12/14/2011  | Sharad        | Initial creation.                                                          *
*
*-------------------------------------------------------------------------------------------------------------*
* HeaderEnd:                                                                                                  *
**************************************************************************************************************/



%macro split_macrovalue(macvar,prefix,splitcnt,dlm=comma,printvalue=N);
%put Start macro split_macrovalue(&macvar,&prefix,&splitcnt,&dlm);

 %if %upcase(&dlm) eq COMMA %then %do; %let dlm=,; %end;
 %else %if %upcase(&dlm) eq PIPE %then %do; %let dlm=|; %end;
 %else %if %upcase(&dlm) eq SPACE %then %do; %let dlm=%str( ); %end;

 %global &splitcnt; /*create the global variable for storing the splitcount*/
 %let num=1; /*initialize a counter variable*/  

 %global &prefix# /*create the global variable for storing the first split*/
 %let &prefix&num=%scan(%superq(&macvar),%superq(num),%superq(dlm)); /*Scan the first value*/
/* %put value here is &&&prefix#*/

/* Remove the comment's to check the values */

      %if %index(%superq(&macvar),%superq(dlm)) gt 0 %then
      %do;
       
       %do %while(%length(&&&prefix&num) gt 0);
            %let &splitcnt=# /*Store the split count to the macro variable reqd*/            
          %let num=%eval(&num + 1);/*increment the counter*/        
          %global &prefix# /*create the global variable*/
          %let &prefix&num=%scan(%superq(&macvar),%superq(num),%superq(dlm)); /*scan the next value*/
/*        %put The next value is &prefix&num=&&&prefix# */
        %end;
      %end;
      %else
      %do
              %let &splitcnt=# /*Store the split count to the macro variable reqd*/ 
      %end;  

      %put The number of values are &&&splitcnt;

      /* Remove the comment's to check the values */
      %if &printvalue=Y %then
      %do;
          
            %do i=1 %to &&&splitcnt;
           %put &prefix&i = &&&prefix&i;
            %end;  
      %end;

%put End macro split_macrovalue;
%mend split_macrovalue;


These macro calls below take the macro variable ‘gender’ with a value list and populate them into a series of macro variables with a prefix ‘gen’…Please note the variations of the delimiters in each of the macro invocations.
 
options mprint mprintnest mlogic mlogicnest;

%let gender = 'F','M';
%split_macrovalue(gender,gen,cnt,dlm=comma,printvalue=Y);

%let gender = 'F'|'M';
%split_macrovalue(gender,sgen,scnt,dlm=pipe,printvalue=Y);

%let gender = 'F' 'M';
%split_macrovalue(gender,tgen,tcnt,dlm=space,printvalue=Y);


I hope these macros help you in simplifying your situations ….


Please let me know if you have any questions.