*
;
/*
    Summary: A splitting macro is given.
    Respondent: Ian Whitlock 

    Trina A. Hosmer   writes

>Hello, I would appreciate any help I can get in programming the following
>task with SAS. I want to read a record and then depending upon the value
>of a keyword, write that record to a SAS file whose name is the matching
>keyword value.
>I know I can do this with "if then ; output keyword", however I have a growing
>number of keywords and do not want to keep adding if then statements to my
>SAS code. Therefore I believe I need a macro to perform the substitution on
>the output name each time. I am having difficulties writing this macro. Thank-
>you in advance for any help I can get performing this task.

    Macros are executed during SAS compilation, hence there is no way to
    avoid the "if --- then output keyword" type of logic although the
    SELECT form would be clearer here.  However you could use macro to
    generate the SELECT block if the keywords were known ahead of time.
    This could be done with a preliminary PROC SUMMARY and DATA step as
    follows.

*/
        %macro split ( data=_last_ , lib=work , dsn=dsn ) ;
            %if %upcase ( &data ) = _LAST_ %then %let data = &syslast ;

            %local i ndsn ;

            /* get list of dsns */
            proc summary data = &data nway ;
               class &dsn ;
               output out = __sumry ( keep = &dsn ) ;
            run ;

            /* turn into array of local macro variables */
            data _null_ ;
               if eof then
                 call symput ( 'ndsn' , left(put(_n_-1,3.)) ) ;
               set __sumry end = eof ;
               call symput ( 'dsn'||left(put(_n_,3.)) , &dsn ) ;
            run ;

            /* do the split */
            data
                  %do i = 1 %to &ndsn ;
                     &lib..&&dsn&i
                  %end ;
               ;
               set &data ;
               select (&dsn) ;
                  %do i = 1 %to &ndsn ;
                     when ("&&dsn&i") output &lib..&&dsn&i ;
                  %end ;
                  otherwise error 'Unexpected value ' &dsn= ;
               end ;
            run ;
        %mend  split ;

/*
    For test code I used

        data w ; do dsn = 'a' , 'b' , 'c' ; output ; end ; run ;
        options mprint ;
        %split ( data = w , dsn=dsn )

    Ian Whitlock  */

*
;