SASマクロ マクロの作成

【SAS】デリミタ区切りの文字列を連番のグローバルマクロ変数に格納する

1.展開例

・シンプルな半角スペース区切りの文字列のマクロ変数化

以下のような、デリミタが半角スペースの文字列をグローバルマクロ変数化してみます。
文字列以外の引数は既定値のまま展開してみます。

%getword(a b c d e f g h i j k l m n o p q r s t u v w x y z);

展開すると、チェックとして、作成されたマクロ変数がログウィンドウに出力されます。

 
以下は、作成したマクロ変数を使用する例です。
シンプルなマクロで展開してみます。

%macro check;

	%put ----- 作成したマクロ変数の展開 -----;

	%local i;
	%do i=1 %to &nword.;
		%put w&i. = &&w&i..;
	%end;
	%put;

%mend check;
%check;

以下のように、意図通りに、連番のマクロ変数が作成されました。

 

・文字列数や接頭辞の引数を指定するパターン

上記の展開例とあんまり変わらないのですが、格納するマクロ変数名を既定値以外に変えて展開するパターンです。

%getword(あいうえお かきくけこ さしすせそ たちつてと なにぬねの, nvar=n_kana, prefix=kana);

先ほどと同様に、展開すると、作成されたマクロ変数がログウィンドウに出力されます。

 
同様に、作成したマクロ変数を使用してみます。

%macro check;

	%local i;
	%do i=1 %to &n_kana.;
		%put kana&i. = &&kana&i..;
	%end;

%mend check;
%check;

以下のように、意図通りにマクロ変数が作成されました。

 

・区切り文字をスペース以外にするパターン

最後は、区切り文字をスペース以外にする場合の展開例です。
文字列自体にスペースが入っている場合は、区切り文字をスペース以外に指定しないと意図通りになりません。
例えば、以下は、デリミタをシャープ#にしています。

%macro conditions;
sex	= 01 #
sex	= 02 #
0 <= age < 20 #
20 <= age #
area in ("千葉", "東京", "神奈川") #
area in ("大分", "宮崎", "鹿児島")
%mend conditions;

%getword(%str(%conditions), nvar=n_cond, prefix=cond, dlm=#);

文字列にイコール「=」やカンマ「,」など、特殊記号が含まれる場合は%STR関数などでクォートして下さい。
 
先ほどと同様に、展開すると、作成されたマクロ変数がログウィンドウに出力されます。

 
同様に、作成したマクロ変数を使用してみます。

%macro check;

	%put ----- 作成したマクロ変数の展開 -----;

	%local i;
	%do i=1 %to &n_cond.;
		%put cond&i. = &&cond&i..;
	%end;
	%put;

%mend check;
%check;

以下のように、意図通りにマクロ変数が作成されました。

 

2.参考プログラム

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

%macro getword(var, nvar=nword, prefix=w, dlm=);
%put --------------------------------------------------;
%put getword;	/*デリミタ区切りの文字列を連番のグローバルマクロ変数に格納する*/
%put &=var;		/*文字列を指定*/
%put &=nvar;	/*文字列数を格納するためのマクロ変数名を指定(既定値=nword)*/
%put &=prefix;	/*グローバルマクロ変数の接頭辞を指定(既定値=w)*/
%put &=dlm;		/*デリミタを指定(既定値=ブランク(スペース区切り))*/
%put --------------------------------------------------;

	/*ローカルマクロ変数の定義*/
	%local check __i;

	/*グローバルマクロ変数の定義*/
	%global &nvar.;

	/*区切り文字がブランクの場合はスペース区切りにする*/
	%if %length(&dlm.) = 0 %then %let dlm = , s;
	
	/*文字列のグローバルマクロ変数化*/
	%let &nvar. = %sysfunc(countw(%superq(var), &dlm.));
	%do __i=1 %to %superq(&nvar.);
		%global &prefix&__i ;
		%let &prefix&__i = %sysfunc(strip(%qscan(%superq(var), &__i, &dlm. ))) ;
	%end;

	/*チェック*/
	%put;
	%put ----- マクロ変数化のチェック開始 -----;
	%put;

	%put &nvar.=%superq(&nvar.);
	%put;

	%let check=3;
	%put ----- 最初と最後の&check.文字列のみチェック -----;
	%put;

	%do __i=1 %to %sysfunc(min(&check., %superq(&nvar.)));
		%put &prefix.&__i.=%superq(&prefix.&__i.);
	%end;
	%do __i=%sysfunc(min(&check., %superq(&nvar.))) %to 1 %by -1;
		%put &prefix.%eval(%superq(&nvar.)-&__i.+1)=%superq(&prefix.%eval(%superq(&nvar.)-&__i.+1));
	%end;

	%put;
	%put ----- マクロ変数化のチェック終了 -----;
	%put;

%mend getword;