/*
/ Program : showhex.sas
/ Version : 1.0
/ Author : Roland Rashleigh-Berry
/ Date : 13-Feb-2007
/ 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
/===============================================================================
/ 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);
%if not %length(&badonly) %then %let badonly=yes;
%let badonly=%upcase(%substr(&badonly,1,1));
%if not %length(&vars) %then %let vars=%varlistc(&dsin);
%local i var words error;
%let error=0;
%if not %length(&dsin) %then %do;
%put ERROR: (showhex) No input dataset specified;
%let error=1;
%end;
%if not %length(&dsout) %then %do;
%put ERROR: (showhex) No output dataset specified;
%let error=1;
%end;
%if &error %then %goto error;
%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;
%error:
%put ERROR: Leaving showhex macro due to error(s) listed;
%skip:
%mend;