%macro mu_wordscan (string= ,root=_root_ ,numw=_numw_ ,delim= ,qtype=UNQUOTE ) / STORE SOURCE des='V1.0.0.19'; %***************************************************************************** FILENAME: MU_WORDSCAN.SAS VERSION: 1.0 DEVELOPER: PPD PLATFORM: SAS 8.2, 9.1.3, and 9.2 on PC SAS PURPOSE: This macro scans a character string and returns: 1. an array of GLOBAL macro variables consisting of the individual elements of the string as defined by a user supplied delimiter. 2. optionally, a GLOBAL macro variable containing the number of elements in the string as defined by a user supplied delimiter PARAMETERS: STRING = The string of words to parse ROOT = The root of the macro variables that are to be defined (default= _root_) NUMW = The number of words parsed (default = _numw_) DELIM = The delimiter separating each word in the string MU_WORDSCAN_RC = return code generated by this program 0 = macro ran successfully 1 = macro did not run successfully MODIFIED BY: DATE: ******************************************************************************; %*EXAMPLES: %MU_WORDSCAN(string=this is a test) This macro will parse the parameter STRING and return global macro variables: _ROOT_1=this _ROOT_2=is _ROOT_3=a _ROOT_4=test _NUMW_=4 %MU_WORDSCAN(string=usubjid rxstart rxstop durat, root=dosvar, numw=num_dosvar) This will resolve the following gloabl macro variables: DOSVAR1=usubjid DOSVAR2=rxstart DOSVAR3=rxstop DOSVAR4=durat NUM_DOSVAR=4 %let varlist=She!sells!sea!shells!by!the!seashore %MU_WORDSCAN(string=&varlist, root=twist, numw=num_twist, delim=!) This will resolve the following gloabl macro variables: TWIST1=she TWIST2=sells TWIST3=sea TWIST4=shells TWIST5=by TWIST6=the TWIST7=seashore NUM_TWIST=7 ******************************************************************************; %local word count; %global &SYSMACRONAME._RC; %let &SYSMACRONAME._rc = 0; %let abort = no; %if &abort = yes %then %goto exit; %let count=1; %if %sysevalf( %superq(string)= ,boolean )=1 %then %do; %put %str(ALERT)_I: parameter STRING is empty in &SYSMACRONAME call; %end; %if &root = %str() %then %do; %put %str(ALERT)_I: parameter ROOT is empty in &SYSMACRONAME call. _ROOT_ will be assigned.; %let root=_root_; %end; %if &numw = %str() %then %do; %put ALERT_I: parameter NUMW is empty in &SYSMACRONAME call. _NUMW_ will be assigned; %let numw = _numw_; %end; %else %if %upcase(&numw) = NUMW %then %do; data _null_; put "ALERT_P: Attempt to GLOBAL a name (NUMW) which exists in a local environment in &SYSMACRONAME call. Program will ABORT."; put "ALERT_P: Assign a different name to the parameter NUMW in &SYSMACRONAME call."; call symputx("&SYSMACRONAME._rc", 1); ABORT; run; %end; %if %sysevalf( %superq(delim)= ,boolean )=1 %then %let delim = %str( ); %* scans the &STRING and finds the first value with the value of count, which is one and has the delimeter set as a &delim; %let word=%qscan(&string,&count,&delim); %* while &WORD is not missing then &ROOT&COUNT is equal to &WORD. Also &COUNT represents the incremental increase. The &STRING is scanned for the first argument. ; %do %while( %sysevalf( %superq(word)= ,boolean )=0 ) ; %global &root&count; %if %qupcase(&qtype.)=UNQUOTE %then %do ; %let &root&count=%unquote(%bquote(&word.)); %end ; %else %if %qupcase(&qtype.)=SUPERQ %then %do ; %let &root&count=%superq(word); %end ; %else %if %qupcase(&qtype.)=NRBQUOTE %then %do ; %let &root&count=%nrbquote(&word.); %end ; %let count=%eval(&count+1); %let word=%qscan(&string,&count,&delim); %end; %* if a value has been specified for macro variable NUMW then a macro variable of that name will be created containing a count of the number of words in the STRING; %if %length(&numw) > 0 %then %do; %global &numw; %let &numw = %eval(&count-1); %end; %**If more than one word, check that the delimiter used in macro variable is the same as the delimiter macro variable***; %let countw=0; %if "&string" ne "" %then %let countw=%sysfunc(countw(&string,' #£$%^&*!@~|/:;,+')); %if &countw gt 1 %then %do; %if %index(&string,&delim)=0 %then %put %str(ALERT)_I: Check that the delimiter is correct; %end; %exit: %put &SYSMACRONAME._RC = &&&SYSMACRONAME._RC; %mend mu_wordscan;