2014年11月4日火曜日

レポート作成インターフェイス(RWI)入門3


今回はRWIで、セル結合する方法を紹介。
(以降、HTMLへの出力が有効になっている前提)


横結合する構文 :  format_cell( column_span: 結合する数 )

data _NULL_;

    dcl odsout ob();
    ob.table_start();

          * 1行目を出力 ;
          ob.row_start();
              ob.format_cell(data:"aa");
              ob.format_cell(data:"bb");
          ob.row_end();

          * 2行目を出力 ;
          ob.row_start();
              ob.format_cell(data:"cc", column_span:2);
          ob.row_end();

    ob.table_end();
run;

結果


縦結合する構文 :  format_cell( row_span: 結合する数 )

data _NULL_;

    dcl odsout ob();
    ob.table_start();

          * 1行目を出力 ;
           ob.row_start();
                ob.format_cell(data:"aa");
                ob.format_cell(data:"bb", row_span:2);
           ob.row_end();

          * 2行目を出力 ;
           ob.row_start();
                ob.format_cell(data:"cc");
           ob.row_end();

    ob.table_end();
run;

結果



実際の使用例

*** サンプルデータ ;
data DT1;
    A="001"; B="AA"; output;
    A="001"; B="BB"; output;
    A="002"; B="CC"; output;
    A="002"; B="DD"; output;
    A="002"; B="EE"; output;
run;

  A  
B
  001 
  AA   
  001
  BB
  002
  CC
  002 
  DD  
  002
  EE

上のサンプルから、RWIを使って以下のように出力してみます。
(Aの値が同じものをセル結合させる)



*** ① Aの値が同じもの同士の数を求める ;
proc sort data=DT1;
    by A;
run;

proc sql;
    create table DT2 as
    select A, count(*) as _COUNT
    from DT1
    group by A;
quit;

  A  
 _COUNT 
 001 
  2
 002
  3


*** ② RWIでセル結合した表を作る ;
data _NULL_;

    merge DT1 DT2 end=EOF;
    by A;

    *** データステップの最初だけ実行する部分 ;
    if _N_=1 then do;

        * RWIを使えるようにして表作成を開始 ;
        dcl odsout ob();
        ob.table_start();

        * 項目名を出力 ;
        ob.head_start();
        ob.row_start();
            ob.format_cell(data:"A");
            ob.format_cell(data:"B");
        ob.row_end();
        ob.head_end();
    end;

    *** データの中身を出力 ;
    ob.row_start();
        if  first.A then  ob.format_cell( data:A, row_span: _COUNT);
        ob.format_cell(data:B);
    ob.row_end();

    *** 最後に表作成を終了 ;
    if EOF then ob.table_end();
run;


ざっくり解説
① まずAの値が同じもの同士の数を求める。
方法はDATAステップでも何でもいいけど、とりあえずSQLで求めてます。

② 次にRWIで表を作ります。ポイントは以下。

if  first.A then  ob.format_cell( data:A, row_span: _COUNT);

BY変数Aの値が同じもの同士の先頭行で、format_cellメソッドを実行。
そこで先にSQLで求めた変数_COUNTをセル結合する数として指定してます。


📝注意


記事の中で使用している「_N_」「END=オプション」「FIRST.BY変数」は「サブセット化IF」と一緒に使用すると正しく動かなくなる事があります。


0 件のコメント:

コメントを投稿