/*------------------------------------------------------------ macro function ValidChs(dsname=,libnm=,encoding=,compatible=); dsname=: dataset name llibnm=: library name optional encoding=: SAS encoding name that to validate characters based on compatible=: SAS encoding name that verify the compatibility to against Automatic macro variable: _validchars_rc has the status of the test 2: No invalid characters are found but data will cause the truncation 1: No invalid characters are found 0: Invalid characters are found -1: Invalid characters are found and also data will cause the truncation -2: General error usage: %validchs(dsname=sashelp.class); %put &_validchars_rc; 0 ---------------------------------------------------------------*/ %global _validchars_rc; %global mydsnm2; %global dsnm0; %global debug; %global invalid; %let mydsnm2=.; %let debug=0; /* localization */ %let msgdataset=sashelp.shell; %macro validchs(dsnm=, libnm=, encoding=, compatible=, rc=); %** need verify the inputs**; %** valid encodings ? **; %if "&encoding" ne "" %then %do; %if %sysfunc(ENCODISVALID(&encoding)) eq 0 %then %do; %put %sysfunc(sasmsg(&msgdataset,validchars_invalidenc_error,n,&encoding)); %let invalid=-2; %goto exit2; %end; %end; /* valid encodings ? */ %if "&compatible" ne "" %then %do; %if %sysfunc(ENCODISVALID(&compatible)) eq 0 %then %do; %put %sysfunc(sasmsg(&msgdataset,validchars_incompatenc_error,n,&compatible)); %let invalid=-2; %goto exit2; %end; %end; %** valid libnm ? **; %if "&libnm" ne "" %then %do; %if "&dsnm" eq "" %then %do; %** n/a validate ALL in the lib **; %put %sysfunc(sasmsg(&msgdataset,validchars_nofunct_error,n)); %let invalid=-2; %goto exit2; %end; %else %do; %** both dsnm and libnm are specified, then combine both **; %let dsnm = %cmpres(&libnm..&dsnm); %end; %end; %else %do; %if "&dsnm" eq "" %then %do; %** if both are not specified **; %put %sysfunc(sasmsg(&msgdataset,validchars_noopt_error,n,%nrstr(Dataset))); %let invalid=-2; %goto exit2; %end; %end; %** get encoding from DS **; %let dsid=%sysfunc(open(&dsnm, i)); %if &dsid eq 0 %then %do; %put %sysfunc(sasmsg(&msgdataset,validchars_nods_error,n,&dsnm)); %let invalid=-2; %goto exit2; %end; %** longceinm contains sas12 name + description, we want sas12 **; %let longceinm=%qsysfunc(attrc(&dsid,%nrstr(encoding))); %let ceil=%index(&longceinm,%str( )); %let dsenc=%substr(&longceinm,1,&ceil); %let dsenc=%sysfunc(trim(&dsenc)); %let rc=%sysfunc(close(&dsid)); %let dsnm0=&dsnm; %** copy DS into WORK to avoid CEDA transcoding **; %if "&dsenc" ^= "&sysencoding" and %qlowcase("&dsenc") ^= "us-ascii" %then %do; %let dpos=%index(&dsnm, .); %if &dpos > 0 %then %do; %let mylib=%substr(&dsnm,1,&dpos-1); %let mydsnm=%substr(&dsnm,&dpos+1); %end; %else %do; %let mylib=work; %let mydsnm=&dsnm; %end; %** test if the mylib is WORK **; %if %UPCASE(&mylib) eq WORK %then %do; %put %sysfunc(sasmsg(&msgdataset,validchars_cedacvt_note,n,&sysencoding)); %let encoding=&sysencoding; %goto tryver; %end; %str(proc sql; create table mytmplibnm as select * from dictionary.libnames where libname=upcase("&mylib"); quit;); %str(data _null_;set mytmplibnm; call symput('pathnm',trim(path)); stop; run;); ;%deleteDS(mytmplibnm); %str(libname tmplib00 "&pathnm" INENCODING=ANY OUTENCODING=ANY ACCESS=READONLY;); %let dsnm=tmplib00.&mydsnm; %end; %tryver: %** try input cei if specified **; %if "&encoding" ne "" %then %do; %let testencoding=&encoding; %end; %else %do; %let testencoding=&dsenc; %end; %let invalid=%verifyDS(dsnm=&dsnm,encoding=&testencoding,debug=&debug); %if "&compatible" eq "" %then %do; %if &invalid=1 %then %do; %** no invalid characters **; %put %sysfunc(sasmsg(&msgdataset,validchars_allvalid_note,n,&dsnm0, &testencoding)); %end; %else %do; %put %sysfunc(sasmsg(&msgdataset,validchars_issue_error,n,&dsnm0,&testencoding)); %end; %end; %** try compatible **; %if "&compatible" ne "" %then %do; %let invalid2=%verifyDS(dsnm=&dsnm,encoding=&testencoding,compatible=&compatible,debug=&debug); %if &invalid2=1 %then %do; %** no invalid characters **; %if &invalid ne 1 %then %put %sysfunc(sasmsg(&msgdataset,validchars_issue_error,n,&dsnm0,&testencoding)); %else %put %sysfunc(sasmsg(&msgdataset,validchars_allcompat_note,n,&dsnm0,&testencoding,&compatible)); %end; %else %do; %put %sysfunc(sasmsg(&msgdataset,validchars_compatissue_error,n,&dsnm0,&testencoding,&compatible)); %end; %end; %if %sysfunc(libref(tmplib00)) = 0 %then %do; %str(libname tmplib00 clear;); %end; %if %sysfunc(exist(&mydsnm2)) %then %do; ;%deleteDS(&mydsnm2);; %let _validchars_rc=&invalid; %return; %end; %exit2: %let _validchars_rc=&invalid; %mend; %macro deleteDS(mydsnm2); %str(proc datasets nolist;delete &mydsnm2;run;quit;) %mend; %macro verifyDS(dsnm=, encoding=, compatible=, debug=); %let obsn=0; %let retval=1; %let dsid=%sysfunc(open(&dsnm, i)); %let num=%sysfunc(attrn(&dsid,nvars)); %do %while (%sysfunc(fetch(&dsid)) eq 0); %let obsn=%eval(&obsn+1); %do i=1 %to # %let name=%sysfunc(varname(&dsid,&i)); %let fmt=%sysfunc(varfmt(&dsid,&i)); %if %sysfunc(vartype(&dsid,&i)) eq %STR(C) %then %do; %let content=%qsysfunc(getvarc(&dsid,&i)); %if &fmt ne "" %then %let content=%qsysfunc(putc(&content,&fmt)); %** test compatibility **; %if "&compatible" ne "" %then %do; %let vl = %sysfunc(varlen(&dsid,&i)); %if &debug eq "YES" %then %do; %let valid = %qsysfunc(VALIDCHAR(&content,&encoding,&compatible,&vl,%STR(DEBUG))); %end; %else %do; %let valid = %qsysfunc(VALIDCHAR(&content,&encoding,&compatible,&vl)); %end; %if &valid eq 0 %then %do; %put %sysfunc(sasmsg(&msgdataset,validchars_invchar_warning,n,&name,&obsn)); %if &retval eq 1 %then %let retval=0; %end; %else %if &valid eq -1 %then %do; %put %sysfunc(sasmsg(&msgdataset,validchars_invtrunc_warning,n,&name,&obsn)); %if &retval eq 1 %then %let retval=-1; %end; %else %if &valid eq 2 %then %do; %put %sysfunc(sasmsg(&msgdataset,validchars_trunc_warning,n,&name,&obsn)); %if &retval eq 1 %then %let retval=2; %end; %else %do; %** all valid chars **; %end; %end; %else %do; %if &debug eq "YES" %then %do; %let valid = %qsysfunc(VALIDCHAR(&content,&encoding,%STR(DEBUG))); %end; %else %do; %let valid = %qsysfunc(VALIDCHAR(&content,&encoding)); %end; %if &valid eq 0 %then %do; %put %sysfunc(sasmsg(&msgdataset,validchars_invchar_warning,n,&name,&obsn)); %if &retval eq 1 %then %let retval=0; %end; %end; %end; %end; %end; %let rc=%sysfunc(close(&dsid)); &retval %mend;