/*
/ Program : showhex.sas
/ Version : 1.0
/ Author : Roland Rashleigh-Berry
/ Date : 04-May-2011
/ Purpose : To create a new dataset where hex characters in character
/ variables are highlighted.
/ SubMacros : %varlistc %words
/ Notes : Variables in the output dataset will have the same name as
/ those in the input dataset but they will be changed to show up
/ hex characters as hex numbers in < > brackets and the variable
/ length will be as defined to the length= parameter. If no
/ variable list is specified then all character variables are
/ assumed. If badonly=yes then an extra variable named __obs is
/ retained in the output dataset set to the matching observation
/ number in the input dataset.
/ Usage : %showhex(test1,test2,cvar1 cvar2 cvar3)
/
/===============================================================================
/ PARAMETERS:
/-------name------- -------------------------description------------------------
/ dsin (pos) name of inout dataset (no modifiers)
/ dsout (pos) name of output dataset (no modifiers)
/ vars (pos) (optional) character variables (separated by spaces)
/ length=200 Length of the new character variables in the output dataset
/ badonly=yes By default keep only those observations where hex characters
/ were found in one or more of the listed character variables.
/===============================================================================
/ AMENDMENT HISTORY:
/ init --date-- mod-id ----------------------description------------------------
/ rrb 13Feb07 "macro called" message added
/ rrb 04May11 Code tidy
/===============================================================================
/ This is public domain software. No guarantee as to suitability or accuracy is
/ given or implied. User uses this code entirely at their own risk.
/=============================================================================*/
%put MACRO CALLED: showhex v1.0;
%macro showhex(dsin,dsout,vars,length=200,badonly=yes);
%local i var words errflag err;
%let err=ERR%str(OR);
%let errflag=0;
%if not %length(&badonly) %then %let badonly=yes;
%let badonly=%upcase(%substr(&badonly,1,1));
%if not %length(&vars) %then %let vars=%varlistc(&dsin);
%if not %length(&dsin) %then %do;
%put &err: (showhex) No input dataset specified;
%let errflag=1;
%end;
%if not %length(&dsout) %then %do;
%put &err: (showhex) No output dataset specified;
%let errflag=1;
%end;
%if &errflag %then %goto exit;
%let words=%words(&vars);
data &dsout;
length __char $ 1 __temp1 __temp2 &vars $ &length;
set &dsin(keep=&vars rename=(
%do i=1 %to &words;
%let var=%scan(&vars,&i,%str( ));
&var=_&var
%end;
));
__bad=0;
__obs=_n_;
%do i=1 %to &words;
%let var=%scan(&vars,&i,%str( ));
__temp1=_&var;
link conv;
&var=__temp2;
%end;
%if "&badonly" EQ "Y" %then %do;
if __bad then output;
%end;
%else %do;
drop __obs;
%end;
drop __temp1 __temp2 __pos __rank __char __i __bad
%do i=1 %to &words;
%let var=%scan(&vars,&i,%str( ));
_&var
%end;
;
return;
conv:
*- converts what is in __temp1 to __temp2 with hex expanded -;
__temp2=' ';
__pos=1;
do __i=1 to length(__temp1);
__char=substr(__temp1,__i,1);
__rank=rank(__char);
if __rank<0020x or __rank>00FFx then do;
*if __rank<0020x or (007Ex < __rank < 00C0x)
and __rank not in (00B0x, 00B4x, 00B5x, 00AEx) then do;
substr(__temp2,__pos,4)='<'||put(__rank,hex2.)||'>';
__pos=__pos+4;
__bad=1;
end;
else do;
substr(__temp2,__pos,1)=__char;
__pos=__pos+1;
end;
end;
return;
run;
%goto skip;
%exit: %put &err: (showhex) Leaving macro due to problem(s) listed;
%skip:
%mend showhex;