Excel操作 SASマクロ

【SAS】Excelシートの指定した範囲をSASデータセット化する(DDE)

1.サンプルファイル

サンプルとして、Excelファイルを開くで開いた以下のファイルを読込みます。
open_excel

 

2.展開例

1.引数informatを指定しないパターン

数値変数として読み込みたいセルに、書式設定などのカンマ「,」が含まれていない場合は、引数informatを省略しても正しく読み込むことができます。

%dde_in(
	file	=都道府県.xlsx,
	sheet	=都道府県,
	top		=4, 
	bot		=10000, 
	col		=2 3 4,
	var		=code name population,
	length	=$2. $10. 8.,
	informat=,
	outdata	=todofuken(where=(not missing(code))),
	outkey	=code
);

しかし、Excelシートの人口にカンマ「,」が含まれていたので、数値変数として正しく読み込めていません。
dde_in_no_informat
 

2.引数informatを指定するパターン

数値として読み込みたいセルにカンマ「,」が含まれているので、入力形式「comma8.」を指定して読込んでみます。

%dde_in(
	file	=都道府県.xlsx,
	sheet	=都道府県,
	top		=4, 
	bot		=10000, 
	col		=2 3 4,
	var		=code name population,
	length	=$2. $10. 8.,
	informat=$2. $10. comma8.,
	outdata	=todofuken(where=(not missing(code))),
	outkey	=code
);

以下のように、数値変数「population」として、正しく読み込むことができました。
dde_in_informat
 

3.列番号を略記法で指定するパターン

今度は、引数colを略記法で指定するパターンを紹介します。
以下のように、引数colに対応させて、その他の引数var、length、informatを指定しています。

%dde_in(
	file	=都道府県.xlsx,
	sheet	=都道府県,
	top		=4, 
	bot		=10000, 
	col		=2-3 4,
	var		=char1-char2 population,
	length	=$10. 8.,
	informat=$10. comma8.,
	outdata	=todofuken(where=(not missing(char1))),
	outkey	=char1
);

注意点として、略記法を使用する場合の変数名varは、「char1-char2」の「char」ように、必ず接頭辞を揃えて下さい。
dde_in_ryakukihou
 

3.参考プログラム

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

%macro dde_in(file=, sheet=, top=, bot=, col=, var=, length=, informat=, outdata=, outkey=);
%put --------------------------------------------------;
%put dde_in;	/*Excelシートの指定した範囲をSASデータセット化するマクロ*/
%put &=file;	/*
				読込対象ファイル名の指定(拡張子は必要、CSVファイルも可)
				ファイル名に「(),」などの特殊記号が含まれる場合はクォートする
				*/
%put &=sheet;	/*
				読込対象シート名の指定
				シート名に「(),」などの特殊記号が含まれる場合はクォートする
				*/
%put &=top;		/*データ部分の上端行番号を指定*/
%put &=bot;		/*データ部分の下端行番号を指定*/
%put &=col;		/*
				読込む列番号を指定(半角スペース区切りで複数指定可)
				略記法で指定する場合は-(ハイフン)の左右は詰めること(例:2-5)
				*/
%put &=var;		/*
				colに対応させて変数名を指定
				略記法で指定する場合は-(ハイフン)の左右は詰めること(例:f2-f5)
				*/
%put &=length;	/*
				colに対応させて変数の長さを指定(省略可)
				省略した場合は長さ510の文字変数となる
				*/
%put &=informat;/*
				colに対応させて入力フォーマットを指定(省略可)
				colに略記法を指定した場合は、その範囲に対し一つの入力形式を指定すること
				*/
%put &=outdata;	/*出力データセット名を指定(データセットオプションの指定可)*/
%put &=outkey;	/*出力ソートキーを指定(省略可)*/
%put --------------------------------------------------;

	/*データの読込*/
	%let __i=1;
	%do %while(%scan(&col.,&__i,,s) ne);

		/*範囲指定かどうかで条件分岐*/
		%if %sysfunc(find(%scan(&col.,&__i,,s),-))>0 %then %do;
			%let col_left =%scan(%scan(&col.,&__i,,s),1,-);
			%let col_right=%scan(%scan(&col.,&__i,,s),2,-);
		%end;
		%else %do;
			%let col_left =%scan(&col.,&__i,,s);
			%let col_right=%scan(&col.,&__i,,s);
		%end;

		filename exc dde "excel|[&file.]&sheet.!r&top.c&col_left.:r&bot.c&col_right.";
		data _dde_in&__i.;

			/*変数の定義*/
			attrib
				%scan(&var.,&__i.,,s)
				%if %length(&length.)>0 %then %do;
					length=%scan(&length.,&__i.,,s)
				%end;
				%else %do;
					length=$510.
				%end;
				%if %length(&informat.)>0 %then %do;
					informat=%scan(&informat.,&__i.,,s)
				%end;
			;
			infile exc notab dlm="09"x dsd missover lrecl=1000000;

			_key+1;
			input %scan(&var.,&__i.,,s);

		run;
		filename exc clear;

		/*カウントアップ*/
		%let __i=%eval(&__i.+1);
	%end;

	/*列数の取得*/
	%let _colnum=%eval(&__i.-1);

	/*各データの結合*/
	data _dde_in_all;
		keep &var.;
		merge
			%do __i=1 %to &_colnum.;
				_dde_in&__i.
			%end;
		;
		by _key;
	run;

	/*出力*/
	data &outdata.;
		set _dde_in_all;
	run;

	/*ソート*/
	%if %length(&outkey.)>0 %then %do;
		proc sort data=&outdata.;
			by &outkey.;
		run;
	%end;

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

%mend dde_in;