たまにはABAP ALV List その3
忘れないうちにやってしまおう企画の第三弾。
今回で一応完成でございます。
前回までで、ずら〜っと選択されていないラジオボタンが、最初の列に表示されるようになったので、今度はボタンをクリックすると選択されるようにして、実行ボタンをつけ、押すとPOPUPで該当レコードのキーを表示する、というところまでやってみようかな〜と思います、はい。
事前に・・・GUIステータス作っときましょう
「実行ボタンをつけ」ってことなので、実行ボタンを作らねばなりませぬ。ということで、GUIステータスを作っておきましょう。
まず、REUSE_ALV_GRID_DISPLAYで使用されているGUIステータスですが、プログラムID:SAPLKKBL、ステータス:STANDARD_FULLSCREENとなっております。これを、自分のテストプログラムにコピーし、実行ボタンをつけるわけです。
今回のサンプルコードは、「YTEST_ALV_LIST」というプログラム名になっているので、それに「Y_TEST_STATUS」というステータスをコピーで作り、機能コード「EXE」というボタンを追加します。
アイコンはなんでもいいので、ご自由に!
GUIステータスの設定
REUSE_ALV_GRID_DISPLAYのGUIステータス設定方法ですが、I_CALLBACK_PF_STATUS_SETのパラメータを使います。
これ、ちょっと面白くって、ここにステータスを直接指定するのではなく、普通のレポートプログラムでGUIステータスを設定するときと同じように、「SET PF-STATUS 'Y_TEST_STATUS'」というソースコードを書いてあるサブルーチン名を指定することになっています。
サブルーチンのパラメータは、「rt_extab TYPE slis_t_extab」となっています。ここらへんは、REUSE_ALV_GRID_DISPLAYのパラメータの内容説明に書いておりますね。英語ですけど。
このパラメータは、使いたくないボタンがあったときに、その機能コードをrt_extabに放り込んでおけば、無効化されますよ〜てなものです。必要に応じて設定すればいい感じです。
さて、今回は、その名も「SET_PF_STATUS」というサブルーチンを作り、そこで、ステータスの設定をすることにいたします。
「ボタンが押されたとき」の対応
続いて、ラジオボタン自体の制御。
ラジオボタンだから、当然どれかをクリックすると、クリックされたところは黒くなり、今まで黒かったところは空白にしたいわけですな。
まず、「どれかをクリックする」というのをハンドルするために、ラジオボタンのフィールドのFEILDCATを変更。hotsoptをOnにします。こうすると、ラジオボタンが押されると、機能コードが発行されるんですな。
発行された機能コードを受け取って、処理を行うためには、REUSE_ALV_GRID_DISPLAYのI_CALLBACK_USER_COMMANDに、その処理が書いてあるサブルーチン名を指定します。
サブルーチンのパラメータは、「u_c_ucomm LIKE sy-ucomm」と、「u_str_field TYPE slis_selfield」となっています。u_c_ucommは、ALVリスト上で押された機能コードが入っていて、u_str_fieldは、押された行の情報だとか、処理終了後にALVリストをリフレッシュするか、とか、そういう指定をするための項目が入ってます。
今回は、「USER_COMMAND」という安直な名前でサブルーチンを作ることにいたします。
ハンドルする機能コードは、ラジオボタンが押されたときの機能コード「&IC1」と、上で作ったGUIステータスについている実行ボタン「EXE」。ラジオボタンの機能コードは、hotspotを指定すると、REUSE_ALV_GRID_DISPLAY側で自動で振られます、はい。
ちなみに、このサブルーチンには、OKコードの最初の文字が%以外のものがやってきます。最初の文字が%のものは、このルーチンにはやってこないで、ALVリストの標準機能が動きます。ダウンロードとか、印刷とか、そんなやつですな。
ということで、一応完成のサンプルコード
まず、ラジオボタンですが、今まで選択されていた行をpre_indexという変数でもっておき、別のラジオボタンが押されたときに、消す行として使います。最初は、DATA_GET内で、一行目にONのラジオボタンを設定しています。
REUSE_ALV_GRID_DISPLAYのパラメータは、I_CALLBACK_PROGRAM、I_CALLBACK_PF_STATUS_SET、I_CALLBACK_USER_COMMANDを追加。I_CALLBACK_PROGRAMは、I_CALLBACK_PF_STATUS_SET、I_CALLBACK_USER_COMMANDで指定するサブルーチンが存在するプログラム名を指定します。同じプログラム内にあるので、sy-repidを入れています。
USER_COMMAND内では、ラジオボタンを押されたときの制御と、実行ボタンを押されたときの制御を入れています。
ラジオボタンを押された場合は、pre_indexに入っている、今までONだった行の項目ICONを、空白ラジオボタンに戻します。u_str_field-tabindexに、選択されたラジオボタンの行が入っているので、該当の行のICONを、ONのラジオボタンに差し替えます。せっかく表示用の内部テーブルを差し替えても、u_str_field-refreshをONにしないとALVリストに反映されないので、フラグを忘れずにたてませう。リフレッシュ時に、カーソルの位置をキープしておきたいので、u_str_field-col_stableと、u_str_field-row_stableもONにしておきます。
実行ボタンの処理は、ちょいと簡単ですが、現在選択されている行のキー項目を、POPUP_DISPLAY_MESSAGEで表示させてみました。pre_indexにONになっている行が入っているので、表示用内部テーブルの該当行をREADし、値をとってきます。
*&---------------------------------------------------------------------* *& Report YTEST_ALV_LIST *& *&---------------------------------------------------------------------* *& *& *&---------------------------------------------------------------------* REPORT YTEST_ALV_LIST. type-pools:slis . type-POOLS:icon . data : itab_feildcat_alv type slis_t_fieldcat_alv . data : itab_out type TABLE OF sflight . data : str_variant like DISVARIANT. data : pre_index like sy-tabix . PARAMETERS p_title type sy-title . START-OF-SELECTION . PERFORM data_get . PERFORM set_feildcat. PERFORM set_variant. PERFORM display_alv . *&---------------------------------------------------------------------* *& Form DATA_GET *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM DATA_GET . data : l_out type YTEST_ALV_LIST . select * from sflight into CORRESPONDING FIELDS OF table itab_out. l_out-icon = ICON_WD_RADIO_BUTTON_EMPTY . MODIFY itab_out FROM l_out TRANSPORTING icon WHERE icon is INITIAL . pre_index = 1. l_out-icon = ICON_RADIOBUTTON . MODIFY itab_out FROM l_out INDEX pre_index TRANSPORTING icon. ENDFORM. " DATA_GET *&---------------------------------------------------------------------* *& Form SET_VARIANT *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM SET_VARIANT . str_variant-report = sy-repid. str_variant-handle = '0001'. ENDFORM. " SET_VARIANT *&---------------------------------------------------------------------* *& Form DISPLAY_ALV *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM DISPLAY_ALV . CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY' EXPORTING * I_INTERFACE_CHECK = ' ' * I_BYPASSING_BUFFER = ' ' * I_BUFFER_ACTIVE = ' ' I_CALLBACK_PROGRAM = sy-repid I_CALLBACK_PF_STATUS_SET = 'SET_PF_STATUS' I_CALLBACK_USER_COMMAND = 'USER_COMMAND' * I_CALLBACK_TOP_OF_PAGE = ' ' * I_CALLBACK_HTML_TOP_OF_PAGE = ' ' * I_CALLBACK_HTML_END_OF_LIST = ' ' * I_STRUCTURE_NAME = 'sflight' * I_BACKGROUND_ID = ' ' I_GRID_TITLE = p_title * I_GRID_SETTINGS = * IS_LAYOUT = IT_FIELDCAT = itab_feildcat_alv * IT_EXCLUDING = * IT_SPECIAL_GROUPS = * IT_SORT = * IT_FILTER = * IS_SEL_HIDE = * I_DEFAULT = 'X' I_SAVE = 'X' IS_VARIANT = str_variant * IT_EVENTS = * IT_EVENT_EXIT = * IS_PRINT = * IS_REPREP_ID = * I_SCREEN_START_COLUMN = 0 * I_SCREEN_START_LINE = 0 * I_SCREEN_END_COLUMN = 0 * I_SCREEN_END_LINE = 0 * I_HTML_HEIGHT_TOP = 0 * I_HTML_HEIGHT_END = 0 * IT_ALV_GRAPHICS = * IT_HYPERLINK = * IT_ADD_FIELDCAT = * IT_EXCEPT_QINFO = * IR_SALV_FULLSCREEN_ADAPTER = * IMPORTING * E_EXIT_CAUSED_BY_CALLER = * ES_EXIT_CAUSED_BY_USER = TABLES T_OUTTAB = itab_out * EXCEPTIONS * PROGRAM_ERROR = 1 * OTHERS = 2 . IF SY-SUBRC <> 0. * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4. ENDIF. ENDFORM. " DISPLAY_ALV *&---------------------------------------------------------------------* *& Form SET_FEILDCAT *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM SET_FEILDCAT . data: l_str_fieldcat type slis_fieldcat_alv , l_tabix like sy-tabix . CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE' EXPORTING I_PROGRAM_NAME = sy-repid * I_INTERNAL_TABNAME = I_STRUCTURE_NAME = 'YTEST_ALV_LIST' * I_CLIENT_NEVER_DISPLAY = 'X' * I_INCLNAME = * I_BYPASSING_BUFFER = * I_BUFFER_ACTIVE = CHANGING CT_FIELDCAT = itab_feildcat_alv * EXCEPTIONS * INCONSISTENT_INTERFACE = 1 * PROGRAM_ERROR = 2 * OTHERS = 3 . IF SY-SUBRC <> 0. * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4. ENDIF. READ TABLE itab_feildcat_alv INTO l_str_fieldcat WITH KEY fieldname = 'ICON' . l_tabix = sy-tabix . l_str_fieldcat-icon = 'X'. l_str_fieldcat-hotspot = 'X'. MODIFY itab_feildcat_alv index l_tabix FROM l_str_fieldcat TRANSPORTING icon hotspot . ENDFORM. " SET_FEILDCAT *&---------------------------------------------------------------------* *& Form SET_PF_STATUS *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM SET_PF_STATUS USING rt_extab TYPE slis_t_extab. SET PF-STATUS 'Y_TEST_STATUS' . ENDFORM. "SET_PF_STATUS *&---------------------------------------------------------------------* *& Form USER_COMMAND *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM USER_COMMAND USING u_c_ucomm LIKE sy-ucomm u_str_field TYPE slis_selfield. data : l_out type YTEST_ALV_LIST , l_message1 type SYMSGV , l_message2 TYPE SYMSGV , l_message3 TYPE SYMSGV. case u_c_ucomm . when '&IC1' . if pre_index is not initial . READ TABLE itab_out INTO l_out INDEX pre_index .. l_out-icon = ICON_WD_RADIO_BUTTON_EMPTY . MODIFY itab_out FROM l_out INDEX pre_index TRANSPORTING icon. ENDIF . READ TABLE itab_out INTO l_out INDEX u_str_field-tabindex. l_out-icon = ICON_RADIOBUTTON . MODIFY itab_out FROM l_out INDEX u_str_field-tabindex TRANSPORTING icon. u_str_field-refresh = 'X'. u_str_field-col_stable = 'X'. u_str_field-row_stable = 'X'. pre_index = u_str_field-tabindex . when 'EXE' . READ TABLE itab_out INTO l_out index pre_index . l_message1 = l_out-CARRID . l_message2 = l_out-CONNID. l_message3 = l_out-FLDATE. CALL FUNCTION 'POPUP_DISPLAY_MESSAGE' EXPORTING TITEL = 'TEST_POPUP' MSGID = '00' MSGTY = 'I' MSGNO = '001' MSGV1 = '選択されたレコード' MSGV2 = l_message1 MSGV3 = l_message2 MSGV4 = l_message3. when OTHERS . ENDCASE .