Type : CREATION_INTERNE
La macro traite uniquement les chaînes de caractères passées en arguments lors de son appel.
| 1 | %macro qcatx /parmbuff; |
| 2 | /*--------------------------------------------------------------------------- |
| 3 | Mimic CATX() function as a macro function. Return results with macro quoting. |
| 4 | |
| 5 | The CAT... series of functions do not work well with %SYSFUNC() because they |
| 6 | can accept either numeric or character values. So %SYSFUNC() has to try |
| 7 | and figure out if the value you passed is a number or a string. Which can |
| 8 | cause unwanted messages in the LOG and worse. |
| 9 | |
| 10 | Example issue with %sysfunc(catx()): |
| 11 | |
| 12 | 1 %put |%sysfunc(catx(^,a,,c))|; |
| 13 | ERROR: %SYSEVALF function has no expression to evaluate. |
| 14 | |a^c| |
| 15 | |
| 16 | This macro uses the PARMBUFF option to accept a virtually unlimited number |
| 17 | of inputs. It then uses %QSCAN() to pull out the delimiter and loops over |
| 18 | the other items emitting them when not empty. |
| 19 | |
| 20 | Examples: |
| 21 | |
| 22 | %* Examples matching CATX() example ; |
| 23 | %put |%qcatx(^,A,B,C,D)| Expect: |A^B^C^D| ; |
| 24 | %put |%qcatx(^,E,,F,G)| Expect: |E^F^G|; |
| 25 | %put |%qcatx(^,H,,J)| Expect: |H^J| ; |
| 26 | |
| 27 | %* Spaces are preserved in delimiter but not other items ; |
| 28 | |
| 29 | %put |%qcatx(^, a ,b , c)| Expect: |a^b^c|; |
| 30 | %put |%qcatx( ,a,b,c)| Expect: |a b c|; |
| 31 | |
| 32 | %* You can use either single or double quotes to protect commas.; |
| 33 | %* The quotes are kept as part of the values.; |
| 34 | |
| 35 | %put |%qcatx(^,a,'b,b',c)| Expect: |a^'b,b'^c|; |
| 36 | %put |%qcatx(",",a,b)| Expect: |a","b|; |
| 37 | |
| 38 | ---------------------------------------------------------------------------*/ |
| 39 | %local dlm i prefix item; |
| 40 | /*--------------------------------------------------------------------------- |
| 41 | SYSPBUFF must have at least 5 characters, like (a,b), for any results to be |
| 42 | produced. First remove () from around SYSPBUFF. Then take first value as |
| 43 | the delimiter. Loop over rests of items. When not empty emit the item. |
| 44 | Use of prefix macro variable enables only writing delimiter between items. |
| 45 | ---------------------------------------------------------------------------*/ |
| 46 | %IF %LENGTH(&syspbuff)>4 %THEN %DO; |
| 47 | %let syspbuff=%qsubstr(&syspbuff,2,%LENGTH(&syspbuff)-2); |
| 48 | %let dlm=%qscan(&syspbuff,1,%str(,),mq); |
| 49 | %DO i=2 %to %sysfunc(countw(&syspbuff,%str(,),mq)); |
| 50 | %let item=%qsysfunc(strip(%qscan(&syspbuff,&i,%str(,),mq))); |
| 51 | %IF %LENGTH(&item) %THEN %DO; |
| 52 | %*;&prefix.&item. |
| 53 | %let prefix=&dlm.; |
| 54 | %END; |
| 55 | %END; |
| 56 | %END; |
| 57 | %mend qcatx; |