ALV開發必備!這里只貼一些粗略的東西,還有一篇關於ALV詳細的文檔,有時間再貼吧
7. ALV
7.1. Layout重要字段
zebra(1) type c, " striped pattern斑馬線顯示,顏色隔行交替顯示
edit(1) type c, " for grid only ALV是否可編輯,注意只對Grid模式有效,對List模式無效
f2code like sy-ucomm, "gs_layout-f2code='&ETA'.雙擊時觸發的Funcode,這里為彈出詳情窗口
colwidth_optimize(1) type c, ALV網格(單元格)寬度設置為自動最優化,按輸出內容寬度自動調整[??pt??ma?z]
lights_fieldname type slis_fieldname," fieldname for exception列顯示為紅綠燈
box_fieldname type slis_fieldname, " fieldname for checkbox指定數據內表中哪列以選擇按鈕形式顯示(首列前可按下或彈上來的按鈕),ALV最左上角會出現全選按鈕
key_hotspot(1) type c, " keys as hotspot " K_KEYHOT設置關鍵字段是否是熱點,可單擊
info_fieldname type slis_fieldname, " infofield for listoutput指定數據輸出內表中哪列存儲的是顏色,用來設置ALV每行數據的顏色
7.2. FIELDCATALOG重要字段
key(1) type c, " column with key-color指定字段是否是關鍵字段,如果是則單元格顯示的顏色會不同,並會靠前顯示
col_pos like sy-cucol, " position of the column列的輸出位置字段在表中第幾列
fieldname type slis_fieldname,"針對輸出內表哪列進行設置,只有設置了的列才會顯示,如果沒有設置,則不會顯示在ALV中。如果此字段是CURR金額(currency field) ,QUAN數量(Quantity field) 需要指定所參照的CUKY貨幣單位、UNIT字段名,需設置Cfieldname Ctabname 和Qfieldname Qtabname
cfieldname type slis_fieldname, "field with currency unit金額字段所參照的貨幣單位字段名
ctabname type slis_tabname, " and table
qfieldname type slis_fieldname, " field with quantity unit數量字段所參照的數量單位字段名
qtabname type slis_tabname, " and table
just(1) type c, " (R)ight (L)eft (C)ent.單元格中內容顯示時對齊方式。不設置時按鈕數據類型默認對齊方式來對齊
lzero(1) type c, " leading zero 為X時輸出前導零
no_sign(1) type c, " write no-sign 不顯示數字符號
no_zero(1) type c, " write no-zero 只輸出有意義的值,空值不輸出。為X時全為零(如:00000)時不輸出,所以不輸出零時應該最好同時設置lzero = sapce與no_zero = X,相反如果要輸出,則應同時設置lzero = X 與no_zero = space
fix_column(1) type c, " Spalte fixieren列固定不滾動,與Key屬性相似,但顏色不會發生變化
do_sum(1) type c, " sum up該列是否進行小計,需與gt_sort-subtot一起使用(即需要參考排序),否則只對整列進行一個合計
seltext_l like dd03p-scrtext_l, " long key word標題字段顯示的名稱(長)
seltext_m like dd03p-scrtext_m, " middle key word標題字段顯示的名稱(中)
seltext_slike dd03p-scrtext_s, " short key word標題字段顯示的名稱(短)
ddictxt(1) type c, " (S)hort (M)iddle (L)ong設置以長、中還是短名稱來顯示,取值分別為 S、M、L。直接指定文本顯示為長文本、中、還是短文本, 指定這個字段后則會固定下來,不會隨着用戶的寬度調整變化.
如果是金額或P小數(數量)類型時,需要對下面兩個屬性進行設置,否則,如果不設置時,在修改對應ALV單元格內容時,會自動將你所輸入的數除100,即小數點提前兩位;並且如果是數量類型,除了設置datatype外,inttype也需要進行設置,且為C:
datatype like dd03p-datatype,數據類型
inttype like dd03p-inttype, 內部類型
ref_fieldname like dd03p-fieldname,"如需單元格顯示F4輸入幫助,則需要指定字段所參照的表名
ref_tabname like dd03p-tabname,"如需單元格顯示F4輸入幫助,則需要指定字段所參照的表中的字段名
另外,以上兩個字段還可以解決ALV中形如參照VBELN、MATNR詞典類型的列導出(自帶的導出功能)Excel時被截斷的問題,具體請參照:ALV自帶導出文件時字段數據末尾被截斷問題
CONVEXIT:設置轉換規則,對應於Domain中的轉換規則,也可用於解決導出Excel數據前導0被截斷的問題
edit(1) type c, " internal use only是否可編輯
hotspot(1) type c, " hotspot設置字段內容下面是否有熱點(有下划線,可點擊,單擊即可觸發相應事件)
7.3. 指定雙擊觸發的FunCode
gs_layout-f2code = '&ETA':設置ALV數據行雙擊觸發的Tcode,這里為彈出詳情窗口
7.4. 相關函數
REUSE_ALV_FIELDCATALOG_MERGE 混合, (使)合並
7.5. 重要參數接口
I_CALLBACK_PF_STATUS_SET 設置工具條
I_CALLBACK_USER_COMMAND用戶點擊工具欄中自定義按鈕、預置按鈕(需通過IT_EVENT_EXIT參數指定預置FunCode才會回調指定的Form)、數據行雙擊、單元格熱點等時,會回調此參數指定的Form
IT_SORT排序、分類匯總
I_SAVE保存表格布局:'X' 只能保存為全局標准變式,'U' 只能保存特定用戶變式,'A'都可以保存,SPACE不能保存變式
I_DEFAULT用戶是否可以設置默認的布局變式(即是否可以將某個布局變式設置為默認的布局)
IS_VARIANT指定布局變式
IT_EVENTS事件回調,可以用來代替I_CALLBACK_USER_COMMAND參數
IT_EVENT_EXIT 預置FunCode回調I_CALLBACK_USER_COMMAND指定的Form
IS_LAYOUT
IT_FIELDCAT
T_OUTTAB需要顯示的數據內表
7.6. 讓預置按鈕回調I_CALLBACK_USER_COMMAND
IT_EVENT_EXIT:讓預置按鈕回調I_CALLBACK_USER_COMMAND 指定的Form。可以向IT_EVENT_EXIT參數內表填充需要被攔截的保留Funcode,及在是執行對應功能代碼之前還是之后調用:
DATA: event_exit TYPE slis_t_event_exit WITH HEADER LINE.
event_exit-ucomm = '&OAD'."此Funcode為點擊AlV工具欄上的選擇布局按鈕所對應的FunCode,會被USER_COMMAND 指定的Form攔截
event_exit-after = 'X'."在執行完預置功能代碼之前還是之后調用
APPEND event_exit.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = sy-repid
it_fieldcat = fieldcat[]
i_callback_user_command = 'USER_COMMAND'
IT_EVENT_EXIT = event_exit[]
TABLES
t_outtab = gt_result.
FORM user_command USING r_ucomm LIKE sy-ucomm rs_selfield TYPE slis_selfield.
ENDFORM.
7.7. 顏色
行顏色:gs_layout-info_fieldname = 'COLOR'."指定數據內表中的哪一列用來作為行顏色的列,顏色值與下面列顏色取值格式是一樣的,也是4位,不同的是此種方式下的顏色值是與顯示數據內表存放在一起,而下面的顏色值則是與gt_fieldcat存放在一起
列顏色:gt_fieldcat-emphasize(['emf?sa?z]強調) = 'C510'."此種方式下的顏色值定義為4位字符,各位含意:
第1位:固定取值為C
第2位COL:顏色值,取值為0~7
第3位INT:高亮,即顏色是否加深,取值為0、1。1表示加深顯示
第4位INV:顏色是否反轉,即顏色是作用在背景上,還是作用在輸出字符上,取值上為0、1。為1時表示設置的是前景色,即輸出字符本身的顏色(好像只有在第3位為0時才有效?)
單元格顏色:gs_layout-coltab_fieldname = 'COLORTABLE'."數據內表中哪列為顏色內表,顏色內表結構如下:
slis_color顏色結構類型各字體對應於上面顏色值串'C510'后三位,意義也是一樣,只是沒有第一位固定字符C
7.8. 可編輯
整體可編輯:gs_layout-edit = 'X'.
某列可編輯:gt_fieldcat-edit = 'X'.
單元格可編輯:只能使用REUSE_ALV_GRID_DISPLAY_LVC,並且還作以下一些設置:
cellstab TYPE lvc_t_styl,"在輸出內表中加上這一類型的列
"先將所有單元格設置為可編輯狀態
gt_fieldcat-edit = 'X'.
DATA: gt_cellstab TYPE lvc_t_styl WITH HEADER LINE.
"再將原本可編輯的單元格切換到不可編輯樣式。注:這里只是樣式的切換,不能僅僅使用cl_gui_alv_grid=>mc_style_enabled來將單元格設置為可編輯狀態,單元格真正是否可編輯是由fieldcat-edit或layout-edit來決定的,而僅設置為cl_gui_alv_grid=>mc_style_enabled是不可編輯的
gt_cellstab-style = cl_gui_alv_grid=>mc_style_disabled.
APPEND gt_cellstab.
gt_data-cellstab = gt_cellstab[].
gs_layout-stylefname = 'CELLSTAB'."數據內表中哪列為可編輯信息內表
7.9. 單元格數據修改后立即自動刷新
單元格中的數據被修改后,將ALV單元格中的數據立即刷新到ABAP對應的內表中:
法一:通過對REUSE_ALV_GRID_DISPLAY函數參數i_grid_settings-edt_cll_cb進行設置:
i_grid_settings-edt_cll_cb = 'X' .
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTINGi_grid_settings = i_grid_settings
法二:通過函數參數I_CALLBACK_USER_COMMAND指定的回調Form的參數slis_selfield進行設置:
FORM user_command USING ucomm LIKE sy-ucommselfield selfield TYPE slis_selfield.
selfield-refresh = 'X'.
CASE ucomm.
WHEN 'UPDATE'.
PERFORM frm_update.
ENDCASE.
ENDFORM.
7.10. 數據有效性驗證事件:data_changed
通過REUSE_ALV_GRID_DISPLAY函數的it_events參數設置DATA_CHANGE事件及事件回調Form:
t_events-name = slis_ev_data_changed.
t_events-form = 'ALV_DATA_CHANGED'.
APPEND t_events.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
it_events = t_events[]
"注:如果沒有設置REUSE_ALV_GRID_DISPLAY 函數的參數i_grid_settings-edt_cll_cb = 'X',在單元格數據被修改后,此Form不會自動調用(即不觸發data_changed事件),直到點擊了保存或刷新按鈕后才會被調用,另外 cl_gui_alv_grid 的CHECK_CHANGED_DATA方法也會觸發 data_changed事件;另外,如果是通過OO實現的ALV,要讓DATA_CHANGE事件觸發,則還需要注冊回車或焦點失去動作,具體參看后面
FORM alv_data_changed USING pel_data TYPE REF TO cl_alv_changed_data_protocol.
DATA: l_name(20),ls_cells TYPE lvc_s_modi.
FIELD-SYMBOLS <fs_value>.
LOOP AT pel_data->mt_mod_cells INTO ls_cells."讀取被修改了的單元格
CLEAR gt_data.
READ TABLE gt_data INDEX ls_cells-row_id."被修改了的單元格所對應輸出內表行數據
CONCATENATE 'GT_DATA-' ls_cells-fieldname INTO l_name. "讀取被單元格所對應的輸出內表中的相應列數據,注:讀取出來是的單元格修改之前的數據
ASSIGN (l_name) TO <fs_value>."<fs_value>即為修改前的值
<fs_value> = ls_cells-value. "ls_cells-value單元格中修改后的新值?
"實際上不需要此句來修改輸出內表中的數據,因為只要在該Form中不彈出 E MSG,則該Form執行完后會也會自動更新輸出內表
"MODIFY gt_data INDEX ls_cells-row_id.
ENDLOOP.
注:如果是通過CL_GUI_ALV_GRID來實現ALV,則在ALV單元格中修改數據后,要在失去焦點或回車時自動觸發DATA_CHANGE事件,則還需要通過CL_GUI_ALV_GRID類的REGISTER_EDIT_EVENT方法來設置發數據改變事件在何時觸發,2 種方式:
2 按回車觸發: i_event_id = cl_gui_alv_grid=>mc_event_enter
2 單元格失去焦點: i_event_id = cl_gui_alv_grid=>mc_event_modifies
必須設置一種方式,要不然數據變化事件不會被觸發事件
7.11. 金額、數字類型輸入問題
對於貨幣與P類型小數(如數量)類型字段,需要對gt_fieldcat-datatype屬性進行設置,才能將輸入的數字保持原樣大小,否則輸入的數據會自動將小數點提前2位;對於數量類型,好像還需要對gt_fieldcat-INTTYPE屬性進行設置才好使,並且只能設置為C類型:
if &1 = 'CURR'.
"對於金額字段,需要設置為 CURR 數據庫字典類型
gt_fieldcat-datatype = 'CURR'.
endif.
if &1 = 'P'.
"對於小數,需要設置為 QUAN 數據庫字典類型
gt_fieldcat-datatype = 'QUAN'.
"除此之外,還需要將inttype類型設置為C類型。另外,按理來說要設置為P類型的,但發現不行,QUAN類型映射為 C類型??
gt_fieldcat-inttype = 'C'.
endif.
7.12. 排序、分類匯總
"決定此列是否進行分類匯總與大匯總。注:如果不設置gt_sort-subtot,則只有大匯總,不會進行分類小匯總
gt_fieldcat-do_sum = 'X'. "設置了gt_fieldcat-do_sum就會有大匯總,分類小匯總要出現的前提之一也是必須要設置此屬性,另外還需對gt_sort-subtot進行設置;如果此參數(gt_fieldcat-do_sum)不設置的話,則大匯總與小匯總都沒有
gt_sort-spos = '1'."排序的順序,如果根據多個字段來排時,決定哪個先排
gt_sort-fieldname = 'KEY1'.
gt_sort-up = 'X'."升序,如果不指定排序(即gt_sort-up、gt_sort-down都沒設置時),默認為升序。只要某字段參設置了gt_sort-down/up,則在展示時,排序以后垂直網格中相鄰相同的單元格就會合並起來(即分類合並,如果要避免合並,請在布局中設置"no_merging"為"X")
"是否需要以此字段進行分類小計(小計匯總)
gt_sort-subtot= 'X'."是否需要以此字段進行分類合並、並進行小計(注:與本列是否參與排序無關系,只要設置此屬性就進行分類合並且小計——但前提是要對gt_fieldcat-do_sum也進行了設置)
APPEND gt_sort.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING it_sort = gt_sort[]
7.13. 可打印的表頭輸出
t_events-name = slis_ev_top_of_page.
t_events-form = 'alv_top_of_page '.
APPEND t_events.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTINGit_events = t_events[]
"頁眉觸發時所回調Form
FORM alv_top_of_page.
DATA:lr_rows TYPE REF TO cl_salv_form_layout_grid,
lr_grid_rows LIKE lr_rows,
lr_row TYPE REF TO cl_salv_form_layout_flow,
lr_logo TYPE REF TO cl_salv_form_layout_logo.
DATA: l_row TYPE i VALUE '1'.
CREATE OBJECT lr_rows.
CREATE OBJECT lr_logo.
...
ENDFORM.
7.14. 布局變式讀取、切換、根據布局格式導出數據
INITIALIZATION.
CALL FUNCTION 'REUSE_ALV_VARIANT_DEFAULT_GET'獲取默認的布局
EXPORTING
i_save = 'A'
CHANGING
cs_variant = gx_variant
p_varit = gx_variant-variant.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_varit.
CALL FUNCTION 'REUSE_ALV_VARIANT_F4'選擇布局
EXPORTING
is_variant = g_variant
i_save = 'A'
p_varit = gx_variant-variant.
START-OF-SELECTION.
DATA: event_exit TYPE slis_t_event_exit WITH HEADER LINE.
event_exit-ucomm = '&OAD'."此Funcode為點擊AlV工具欄上的選擇布局按鈕時 會被USER_COMMAND Form攔截
event_exit-after = 'X'.
APPEND event_exit.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_save = 'A'
i_callback_user_command = 'USER_COMMAND1'
it_event_exit = event_exit[]
is_variant = g_variant "ALV展示時,所使用的布局變式名。如果不存在,按默認來
FORM user_command1 USING r_ucomm LIKE sy-ucomm rs_selfield TYPE slis_selfield.
CASE r_ucomm.
WHEN '&OAD'."當點擊選擇布局按鈕時執行
DATA l_ref1 TYPE REF TO cl_gui_alv_grid.
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'獲取當前ALV所對應的OO Grid
IMPORTING e_grid = l_ref1.
l_ref1->get_variant( IMPORTING es_variant = l_variant )
DATA:p_fieldcat_tab TYPE slis_t_fieldcat_alv.
"當知道當前用戶所選擇的布局變式后,再通過函數 REUSE_ALV_VARIANT_SELECT 可以
"得到布局變式所對應的布局具體信息,如哪些字段顯示、字段顯示的順序如何等,當得到這些
"布局信息后,可以用在用戶在導出ALV數據到文件時使用,這樣可以保持ALV顯示的布局與
"導出去的文件顯示的哪些內容及字段順序體質一致
CALL FUNCTION 'REUSE_ALV_VARIANT_SELECT'讀取布局信息
IMPORTING
"可以根據返回的p_fieldcat_tab,得到當前ALV所使用的布局變式所對應的Layout情況,如
"將ALV數據下載成文件時需要與當前Layout布局一樣:輸出相同的字段與順序,可以根據
"p_fieldcat_tab 的 NO_OUT(控制是否輸出)、COL_POS(控制順序)來控制,文件表頭可取
"seltext_l、seltext_m或seltext_s。可用於導出文件布局
et_fieldcat = p_fieldcat_tab[]
CHANGING
cs_variant = l_variant."傳入的布局布局變式名
"""""""下面就是對 p_fieldcat_tab[] 內表字段結構進行分析及應用了
....
ENDCASE.
ENDFORM.
7.15. 動態內表
另外,在ALV中可以根據FieldCat來動態創建內表:
rt_fieldcatalog type lvc_t_fcat.
CALL METHOD cl_alv_table_create=>create_dynamic_table [dai?n?mik]
EXPORTING
it_fieldcatalog = rt_fieldcatalog[]
IMPORTING
ep_table = g_table.
8. OO ALV
8.1. 相關類
8.2. 控制區域、容器、Grid關系
先在屏幕上繪制一個用戶自定義控件區域,然后該用戶以自定義控件區域為基礎來創建CL_GUI_CUSTOM_CONTAINER容器實例,最后以此容器實例來創建CL_GUI_ALV_GRID實例
8.3. CL_GUI_ALV_GRID重要方法
set_table_for_first_dispaly
REFRESH_TABLE_DISPLAY
IS_STABLE: 刷新的穩定性,就是滾動條保持不動
I_SOFT_REFRESH: 軟刷新,如果設置了這個參數,臨時給ALV創建的合計、排序、數據過濾都將保持不變。這個是非常有意義的,例如:當你沒有修改數據內表里的數據,但因布局修改了想刷新ALV時可使用
8.4. set_table_for_first_dispaly()方法重要參數
I_SAVE I_DEFAULT |
IT_FIELDCATALOG |
IT_SORT |
8.5. 事件綁定、觸發、回調處理
CLASS cl_event_handle DEFINITION. "定義事件處理類
PUBLIC SECTION.
"ALV工具欄初始化事件,如增加按鈕並設定屬性
METHODS handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
IMPORTING e_object e_interactive.
"ALV工具欄按鈕點擊事件
METHODS handle_user_command FOR EVENT user_command OF cl_gui_alv_grid
IMPORTING e_ucomm.
"ALV表格雙擊事件
METHODS handle_double_click FOR EVENT double_click OF cl_gui_alv_grid
IMPORTING e_row e_column es_row_no.
ENDCLASS.
CLASS cl_event_handle IMPLEMENTATION."事件處理類實現部分
METHOD handle_toolbar.
gs_toolbar-function = 'B_SUM'."按鈕的FunctionCode
gs_toolbar-icon = icon_display."按鈕圖標
gs_toolbar-text = '總行數'."按鈕標簽
gs_toolbar-butn_type = '0'."定義按鈕類型,0為標准按鈕
APPEND gs_toolbar TO e_object->mt_toolbar."添加按鈕到工具欄中
ENDMETHOD.
METHOD handle_user_command.
DATA: sum TYPE i .
IF e_ucomm = 'B_SUM'.
...
ENDIF.
ENDMETHOD.
METHOD handle_double_click.
....
ENDMETHOD.
ENDCLASS.
CREATE OBJECT container_r EXPORTING container_name = 'CONTAINER_1'."創建ALV容器對象
CREATE OBJECT grid_r EXPORTING i_parent = container_r. "創建ALV控件
CALL METHOD grid_r->set_table_for_first_displayCHANGING it_outtab = gt_sflight[].
SET HANDLER :event_handle->handle_toolbar FOR grid_r, "注冊處理器
event_handle->handle_user_command FOR grid_r,
event_handle->handle_double_click FOR grid_r.
CALL METHOD grid_r->set_toolbar_interactive. "調用此方法才能激活工具欄上增加的自定義按鈕
8.6. CL_GUI_DOCKING_CONTAINER容器
Docking容器最大特點是在代碼中可以動態創建容器,不需要像創建自定義容器CL_GUI_CUSTOM_CONTAINER那樣,在創建時需要將其綁定到一個預先繪制好的用戶自定義控件區域中
8.7. 覆蓋(攔截)預設按鈕的功能FunCode:BEFORE_USER_COMMAND
在before_user_command事件中截取標准的功能,完成其他功能,然后使用方法set_user_command將功能代碼修改為空(如何攔截事件,則參考事件綁定、觸發、回調處理章節)
FORM handle_before_user_command USING i_ucomm TYPE syucomm .
CASE e_ucomm .
WHEN '&INFO' .
CALL FUNCTION 'ZSFLIGHT_PROG_INFO'.
CALL METHOD gr_alvgrid->set_user_commandEXPORTING i_ucomm = space.
ENDCASE .
ENDFORM .
8.8. 數據改變事件data_changed、data_changed_finished
Alv grid有兩個事件:data_changed和ata_changed_finished.第一個事件在可編輯字段的數據發生變化時觸發,可用來檢查數據的輸入正確性,第二個事件是當數據修改完成后觸發
如果數據沒有被修改,當失去焦點或回車時,那么它不會走data change,而是直接觸發data change finish事件
可以通過CL_GUI_ALV_GRID類的REGISTER_EDIT_EVENT方法來設置在失去焦點或回車時,觸發數據改變事件:
2 按回車觸發: i_event_id = cl_gui_alv_grid=>mc_event_enter
2 單元格失去焦點: i_event_id = cl_gui_alv_grid=>mc_event_modifies
必須設置一種方式,要不然數據變化事件不會被觸發事件
然后注冊CL_GUI_ALV_GRID的data_changed、data_changed_finished事件,實現事件處理器方法,在數據發生改變時就會觸發這兩上事件