SASマクロ チェック作業

【SAS】文字切れの可能性がある文字変数をチェックする

1.サンプルデータ

サンプルとして、以下のデータを使用します。
今回はあえて、変数hojin_nameの長さを短めに指定しています。

data hojin_list;
	infile datalines dlm="," dsd missover;
	input no hojin_name:$30.;
datalines;
1,日本郵船株式会社
2,株式会社Mizkan J plus Holdings
3,公益社団法人福岡医療団
4,社団医療法人 啓愛会
5,一般社団法人 北陸地区信用金庫協会
6,兵庫県弁護士協同組合
7,学校法人 藤田学園
8,一般財団法人東北電気保安協会
9,社会医療法人蘇西厚生会
10,公益社団法人福岡医療団
11,田中貴金属労働組合
12,医療法人社団 友愛病院会
13,東京海上日動調査サービス共済組合
14,社会医療法人財団白十字会
15,オカムラグループ健康保険組合
16,日本ヒューレット・パッカード合同会社
17,社団医療法人 啓愛会
;
run;

hojin_list_short_length
 

2.展開例

%check_length(indata=hojin_list, outdata=error_length);

指定した変数の長さが足りず、文字切れの可能性がある変数と変数値がログに出力されます。
check_length_log
 
引数outdataにデータセット名を指定すると、以下のような、データセットが出力されます。
check_length_error
 

3.参考プログラム

以下は、参考プログラムになります。
右上のコピーボタンを押せば、プログラム全体をコピーできます。

%macro check_length(indata=, var=, outdata=);
%put --------------------------------------------------;
%put check_length;	/*文字切れの可能性がある文字変数をチェックする*/
%put &=indata;		/*入力データセットを指定(データオプションの指定可)*/
%put &=var;			/*チェック対象の文字変数を指定(省略した場合は全文字変数が対象となる)*/
%put &=outdata;		/*エラー変数を出力するデータセットを指定(省略した場合はログのみ出力する)*/
%put --------------------------------------------------;

	/*ローカルマクロ変数の定義*/
	%local i varnum name;

	/*データの読み込み*/
	data _check_length_data;
		%if %length(&var.) > 0 %then %do;
			format &var.;
			keep &var.;
		%end;
		set &indata.;
	run;

	%if &sysnobs.= 0 %then %do;
		%put WARNING:入力データセットは空です。;
		%put WARNING:%nrstr(%check_length)を終了します。;
		%goto exit;
	%end;

	/*変数情報の取得*/
	proc contents	data=_check_length_data 
					out =_check_length_cont(where=(type=2))
					noprint;
	run;
	proc sort data=_check_length_cont;
		by varnum;
	run;
	
	%if &sysnobs.= 0 %then %do;
		%put WARNING:文字変数が存在しません。;
		%put WARNING:%nrstr(%check_length)を終了します。;
		%goto exit;
	%end;

	/*変数情報のマクロ変数化*/
	data _null_;
		set _check_length_cont;
		call symputx("varnum", _n_);
		call symputx(cats("var", _n_), name);
	run;

	/*チェック*/
	data 
		%if %length(&outdata.) > 0 %then %do;
			&outdata.;
			keep _vname_ _vlength_ _obs_ _value_;
			length _vname_ $32. _vlength_ _obs_ 8. _value_ $32767.;
			label
				_vname_		="変数名"
				_vlength_	="変数長さ"
				_obs_		="オブザベーション番号"
				_value_		="文字切れの可能性がある変数値"
			;	
		%end;
		%else %do;
			_null_;
		%end;
		
		set _check_length_data;

		/*配列名を自動マクロ変数sysindexで作成。システム的に重複しない値が付与される*/
		%let name = &sysindex.;
		array ar_&name.
			%do i=1 %to &varnum.;
				&&var&i..
			%end;
		;

		do over ar_&name.;
			_vlength_ = length(ar_&name.);
			if _vlength_ = vlength(ar_&name.) then do;
				put "WARNING:文字切れの可能性があります。変数長さ(" _vlength_ +(-1) "byte)" +1 ar_&name.=;
				
				%if %length(&outdata.) > 0 %then %do;
					_vname_	=vname(ar_&name.);
					_obs_	=_n_;
					_value_	=ar_&name.;
					output &outdata.;
				%end;
			end;
		end;
	run;

	/*ソートして出力*/
	%if %length(&outdata.) > 0 %then %do;
		proc sort data=&outdata.;
			by _vname_ _obs_;
		run;
	%end;
		
	/*%GOTO先*/
	%exit:

	/*不要データの削除*/
	proc datasets lib=work noprint;
		delete _check_length_:;
	quit;

%mend check_length;