2017年10月3日火曜日

【PROC REPORT】1つの項目に複数のCALL DEFINEを定義したい




「CALL DEFINEの重ね着って出来ないんですか?」って質問をたまにいただきます。


どういう事かと言うと、以下の例をご覧ください。

proc report data=SASHELP.CLASS nowd;
    column NAME AGE ;
    define NAME / display;
    define AGE / display;
    compute AGE;
       if AGE > 13 then call define( "name", "style", "style=[color=blue]" );
       if AGE > 14 then call define( "name", "style", "style=[background=yellow]" );
    endcomp;
run;

CALL DEFINEで、

① AGE>13の時、変数NAMEの値を青色にする
② AGE>14の時、変数NAMEの背景色を黄色にする

という事をしてます。

よくみると、Janetさんは値を青にした上で、背景色を黄色にしたかったんですが、青くなってません。


CALL DEFINEで定義したSTYLEが、1つのセルに対して1つしか適用されていないようです。
STYLEの適用順は状況によって異なりますが、今回は「①値を青色」→「②背景色を黄色」の順で適用されているようですね。



そこで、小技。
以下のように「STYLE/MERGE」とすれば、複数のCALL DEFINEによるSTYLEを、上書きじゃなくてMERGE(結合)してくれます。

proc report data=SASHELP.CLASS nowd;
    column NAME AGE ;
    define NAME / display;
    define AGE / display;
    compute AGE;
       if AGE > 13 then call define( "name", "style", "style=[color=blue]" );
       if AGE > 14 then call define( "name", "style/merge", "style=[background=yellow]" );
    endcomp;
run;

ちゃんとJanetさんが青くなってますね。


ちなみに、
本題からズレますが、CALL DEFINEを書くために利用しているCOMPUTEステートメントは高頻度でうまく設定できないケースを見かけるので、以下記事と以下記事内にリンクしている記事も要確認です。




📝その他、混乱しそうなポイント

以下みたいに一方が「_ROW_」だと、「STYLE/MERGE」としなくても1つのセルに複数のSTYLEが設定できました。

proc report data=SASHELP.CLASS nowd;
    column NAME AGE ;
    define NAME / display;
    define AGE / display;
    compute AGE;
       if AGE = 14 then call define( "name", "style", "style=[color=blue]" );
       if AGE = 14 then call define( _row_, "style", "style=[background=yellow]" );
    endcomp;
run;


ただ、以下の場合ちょっと混乱しそう。

proc report data=SASHELP.CLASS nowd;
    column NAME AGE ;
    define NAME / display;
    define AGE / display;
    compute AGE;
       if AGE = 14 then call define( "name", "style", "style=[color=blue]" );
       if AGE = 14 then call define( _row_, "style", "style=[color=red]" );
    endcomp;
run;


最後「_ROW_」で行の全変数の文字色を赤にしたはずなのに、NAMEの文字色が青になってる?
プログラムの記述順で、STYLEが適用されると思いがちですが、違うっぽい。
2番目の以下「_ROW_」のSTYLEが先に実行されて、、

 if AGE = 14 then call define( _row_, "style", "style=[color=red]" );


次に1番目の以下STYLEが適用されたような挙動です。

 if AGE = 14 then call define( "name", "style", "style=[color=blue]" );



本題から逸れましたが、こんな感じで動きが独特なのでご注意ください。


0 件のコメント:

コメントを投稿