1. 程式人生 > >ALV詳解:Function ALV(一)

ALV詳解:Function ALV(一)

Function ALV

Layout結構

Fieldcat結構

ALV相關函式

簡單例項

Fieldcat動態建立

通過程式設計建立

通過REUSE_ALV_FIELDCATALOG_MERGE函式建立

自定義ALV工具條

快速拷貝GUI Status

ALV事件

所支援事件

工具條預置按鈕回調出口IT_EVENT_EXIT

顏色

行顏色

列顏色

單元格顏色

可編輯

PushButton

Function ALV

ALV:SAPListViewer

ALV顯示格式分為GRID及LIST兩種模式,一個以網格顯示,另一個以表格顯示,兩者都有工具欄稍有不同

Layout結構

Layout主要用於設定ALV整體輸出格式,為ALV可選項引數。屬於型別池 TYPE-POOLS:SLIS

TYPE-POOLS:slis.
DATA: layout TYPE slis_layout_alv.

Layout結構所定義的所有欄位如下(各欄位詳細使用說明,可參考REUSE_ALV_GRID_DISPLAY的 is_layout引數文件說明):

     no_colhead(1) type c,         " no headings不顯示列標題行
     no_hotspot(1) type c,         " headings not as hotspot
     zebra(1) type c,              " striped pattern斑馬線顯示,顏色隔行交替顯示
     no_vline(1) type c,           " columns separated by space不顯示垂直網格線
     no_hline(1) type c,        "rows separated by space B20K8A0N5D不顯示水平網格線
     cell_merge(1) type c,         " not suppress field replication  ALV單元格中的內容能夠複製到剪貼簿

edit(1) type c, " for grid onlyALV是否可編輯,注意只對Grid模式有效,對List模式無效
edit_mode(1) type c, " for grid only
numc_sum(1) type c, " totals for NUMC-Fields possib.
no_input(1) type c, " only display fields
f2code like sy-ucomm, "gs_layout-f2code = ‘&ETA’.設定觸發彈出詳細資訊視窗的功能碼,這裡是雙擊(&ETA)就可以彈出詳細視窗,而不需要通過右鍵選單
reprep(1) type c, " report report interface active
no_keyfix(1) type c, " do not fix keycolumns
expand_all(1) type c, " Expand all positions
no_author(1) type c, " No standard authority check

  •    PF-status
       def_status(1) type c,         " default status  space or 'A'
       item_text(20) type c,         " Text for item button
       countfname type lvc_fname,
    
  •    Display options
    

colwidth_optimize(1) type c, ALV網格(單元格)寬度設定為自動最優化,按輸出內容寬度自動調整
no_min_linesize(1) type c, " line size = width of the list
min_linesize like sy-linsz, " if initial min_linesize = 80
max_linesize like sy-linsz, " Default 250
window_titlebar like sy-title,
no_uline_hs(1) type c,

  •    Exceptions
       lights_fieldname type slis_fieldname," fieldname for exception列顯示為紅綠燈
       lights_tabname type slis_tabname, " fieldname for exception
       lights_rollname like dfies-rollname," rollname f. exceptiondocu
       lights_condense(1) type c,    " fieldname for exception
    
  •    Sums
       no_sumchoice(1) type c,       " no choice for summing up
       no_totalline(1) type c,       " no total line
       no_subchoice(1) type c,       " no choice for subtotals
       no_subtotals(1) type c,       " no subtotals possible
       no_unit_splitting type c,     " no sep. tot.lines by inh.units
    

totals_before_items type c, " diplay totals before the items統計行會在資料行前面顯示
totals_only(1) type c, " show only totals只顯示合計
totals_text(60) type c, " text for 1st col. in total line合計第一列文字
subtotals_text(60) type c, " text for 1st col. in subtotals

  •    Interaction互動
    

box_fieldname type slis_fieldname, " fieldname for checkbox指定資料內表中哪列以選擇按鈕形式顯示(首列前可按下或彈上來的按鈕),ALV最左上角會出現全選按鈕image001[6]
box_tabname type slis_tabname," tabname for checkbox
box_rollname like dd03p-rollname," rollname for checkbox
expand_fieldname type slis_fieldname, " fieldname flag ‘expand’
hotspot_fieldname type slis_fieldname, " fieldname flag hotspot
confirmation_prompt, " confirm. prompt when leaving當退出image002[6]ALV報表展示介面時,是否需要提示使用者
key_hotspot(1) type c, " keys as hotspot " K_KEYHOT設定關鍵欄位是否是熱點,可單擊
flexible_key(1) type c, " key columns movable,…
group_buttons(1) type c, " buttons for COL1 - COL5
get_selinfos(1) type c, " read selection screen
group_change_edit(1) type c, " Settings by user for new group
no_scrolling(1) type c, " no scrolling

  •    Detailed screen詳細螢幕
       detail_popup(1) type c,       " show detail in popup 右鍵中有 Detail 選單,是否彈出詳細資訊視窗
       detail_initial_lines(1) type c, " show also initial lines為空行時單元格內容也會顯示在右鍵彈出的詳細框中
       detail_titlebar like sy-title," Titlebar for detail設定詳細彈出視窗的標題欄
    
  •    Display variants
       header_text(20) type c,       " Text for header button
       default_item(1) type c,       " Items as default
    
  •    colour顏色
    

info_fieldname type slis_fieldname, " infofield for listoutput指定資料輸出內表中哪列儲存的是顏色,用來設定ALV每行資料的顏色。注:使用屬性需要同時在資料內表中定義一個與該引數所定義欄位名相同的欄位,如:LAYOUT-INFO_FIELDNAME=’COLOR’,假設資料內表名為LT_OUT,則需要在該內表增加一個欄們“COLOR”,顏色範圍 C000~C999
coltab_fieldname type slis_fieldname, " colors

  •    others
       list_append(1) type c,       " no call screen
       xifunckey type aqs_xikey,    " eXtended interaction(SAPQuery)
       xidirect type flag,          " eXtended INTeraction(SAPQuery)
       dtc_layout type dtc_s_layo,  "Layout for configure the Tabstip
       allow_switch_to_list(1) type c, "ACC: Switch from FullGrid to List
    

Fieldcat結構

Fieldcat主要用於ALV資料顯示結構的定義,包括具體的欄位名稱、型別、各欄位的輸出格式(與Layout不一樣的是輸出格式只針對某個欄位),為ALV必選引數

TYPE-POOLS:slis.
DATA: fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE.

Fieldcat結構所定義的所有欄位如下(各欄位詳細使用說明,可參考REUSE_ALV_GRID_DISPLAY的 it_fieldcat引數文件說明):

 row_pos        like sy-curow, " output in row
     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
     tabname        type slis_tabname,

currency(5) type c, TCURX表中的貨幣名稱
cfieldname type slis_fieldname, " field with currency unit金額欄位所參照的貨幣單位欄位名稱(貨幣單位欄位為資料內表中的某列?)
ctabname type slis_tabname, " and table
ifieldname type slis_fieldname, " initial column
quantity(3) type c,計量單位
qfieldname type slis_fieldname, " field with quantity unit
qtabname type slis_tabname, " and table
roundtypei, " round in write statement四捨五入至小數點後多少位
exponent(3) type c, " exponent for floats浮點數的冪指數為多少位
key(1) type c, " column with key-color指定欄位是否是關鍵欄位,如果是則單元格顯示的顏色會不同,並會靠前顯示
icon(1) type c, " as icon欄位將以圖示形式顯示,INCLUDE ,圖示欄位內容來自list Inc.檔案
symbol(1) type c, " as symbol欄位內容作為符號輸出,與上面的ICON屬性相似
checkbox(1) type c, " as checkbox欄位將以複選框形式顯示
just(1) type c, " ®ight (L)eft ©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
no_convext(1) type c,
edit_mask type slis_edit_mask, "對欄位內容進行掩碼格式化輸出,具體請參照《ABAP BC Programming.docx》中的WRITE … TO章節,如:gt_fieldcat-edit_mask = '____//'可對日期欄位都日期格式化顯示
emphasize(4) type c, " emphasize設定列的顏色
fix_column(1) type c, " Spalte fixieren列固定不滾動,與Key屬性相似,但顏色不會發生變化
do_sum(1) type c, " sum up該列是否進行小計,需與gt_sort-subtot一起使用(即需要參考排序),否則只對整列進行一個合計
no_out(1) type c, " (O)blig.(X)no out但注意使用者可以change layout(佈局設定)來顯示出此列
tech(1) type c, " technical field該欄位為技術欄位:設定為技術列的列將不會再顯示出來,即使是在佈局設定裡也是看不到的
outputlen like dd03p-outputlen,列的字元輸出寬度
offset type dd03p-outputlen, " offset

調整輸出列擡頭的文字:文字可以隨著使用者調整列的寬度而變化,其文字即是在對應data element中定義的,如果需要定製,則可以指定以下欄位
seltext_l like dd03p-scrtext_l, " long key word標題欄位顯示的名稱(長)
seltext_m like dd03p-scrtext_m, " middle key word標題欄位顯示的名稱(中)
seltext_s like dd03p-scrtext_s, " short key word標題欄位顯示的名稱(短)
ddictxt(1) type c, " (S)hort (M)iddle (L)ong設定以長、中還是短名稱來顯示,取值分別為 S、M、L。直接指定文字顯示為長文字、中、還是短文字, 指定這個欄位後則會固定下來,不會隨著使用者的寬度調整變化.
reptext_ddic like dd03p-reptext, " heading (ddic),(header) Analogous(相似) to the Data element main header

rollname like dd03p-rollname,F1幫助需參照的DataElement,在ALV的顯示介面將滑鼠放到該欄位的位置後按F1會彈出該欄位的說明。另外,可以不指明欄位的描述(如seltext_l、seltext_m、seltext_s),函式會自動將欄位的描述顯示為該參照的資料元素

下面datatype兩個屬性在欄位如果是金額或P小數(數量)型別時,需要對datatype此屬性進行設定,否則,如果不設定時,在修改對應單元格內容時,會自動將你所輸入的數除100,即小數點提前兩位;並且如果是數量型別,除了設定datatype外,inttype也需要進行設定,且為 C,具體實現請參考這裡
datatype like dd03p-datatype,
inttype like dd03p-inttype,
intlen like dd03p-intlen,
lowercase like dd03p-lowercase,

     ref_fieldname  like dd03p-fieldname,"如需單元格顯示F4輸入幫助,則需要指定欄位所參照的表名
     ref_tabname    like dd03p-tabname,"如需單元格顯示F4輸入幫助,則需要指定欄位所參照的表中的欄位名
     roundfieldname type slis_fieldname,
     roundtabname   type slis_tabname,
     decimalsfieldname type slis_fieldname,
     decimalstabname   type slis_tabname,
     decimals_out(6)   type c,     " decimals in write statement控制小數點的位數
     text_fieldname type slis_fieldname,         
     ddic_outputlen like dd03p-outputlen,



     key_sel(1)     type c,        " field not obligatory
     no_sum(1)      type c,        " do not sum up
     sp_group(4)    type c,        " group specification
     reprep(1)      type c,        " selection for rep/rep

input(1) type c, " input
edit(1) type c, " internal use only是否可編輯
hotspot(1) type c, " hotspot設定欄位內容下面是否有熱點(有下劃線,可點選,單擊即可觸發相應事件)

ALV相關函式

REUSE_ALV_GRID_DISPLAY:Grid 格式的ALV

REUSE_ALV_LIST_DISPLAY: LIST格式的 ALV

REUSE_ALV_FIELDCATALOG_MERGE:根據程式中的資料內表結構,來自動生成FIELDCAT[]內表,會根據內表結構所參照的詞典型別來自動完成如表標題欄位名的生成,得到大概的FIELDCAT[]後,可以再根據特殊情況再修改FIELDCAT[]內表,這樣可以大大減少FIELDCAT[]內表的建立工作。注:程式中用來輸出的內表結構中的每個欄位都要參考了資料字典中的Data element,否則無法獲取欄位的相關資訊,此時在自動構建FIELDCAT後再手動對無參照字典型別的欄位進行手工設定

注:還有一種以 LVC結尾的ALV函式REUSE_ALV_GRID_DISPLAY_LVC,此函式中引用到的型別大部分都不再從型別池slis 中來引用(TYPE-POOLS:slis.),而是直接引用字典中已定義好的表或結構型別,這種函式屬於新性函式,與面向物件的CL_GUI_ALV_GRID生成的ALV引數型別上基本相同,所以以後一般如果使用函式方式來產生ALV,推薦使用REUSE_ALV_GRID_DISPLAY_LVC函式,而非REUSE_ALV_GRID_DISPLAY函式因為這樣方便修改面向物件方式的ALV

REUSE_ALV_GRID_DISPLAY與REUSE_ALV_LIST_DISPLAY函式的引數基本相同:

CALLFUNCTION’REUSE_ALV_GRID_DISPLAY’

  • EXPORTING
  • I_INTERFACE_CHECK = ’ ’
  • I_BYPASSING_BUFFER = ’ ’
  • I_BUFFER_ACTIVE = ’ ’
  • I_CALLBACK_PROGRAM = ’ '回撥函式、待輸出資料內表所在的程式名,一般為本程式,但一般不要直接使用SY-REPID系統變數,因為可能出現多層次呼叫(一個程式呼叫另一程式,形成呼叫鏈時)SY-REPID可能不是最後想要的程式
  • I_CALLBACK_PF_STATUS_SET = ’ '設定工具欄
  • I_CALLBACK_USER_COMMAND = ’ '工具欄按鈕或資料行事件觸發時所要呼叫的Form
  • I_CALLBACK_TOP_OF_PAGE = ’ ’
  • I_CALLBACK_HTML_TOP_OF_PAGE = ’ ’
  • I_CALLBACK_HTML_END_OF_LIST = ’ ’
  • I_STRUCTURE_NAME =如果輸出內表的結構參照的就是表結構,則可以不用指定fieldcat,直接使用這個詞典結構,函式會自動根據此結構來生成fieldcat。在實際業務中一般是從多個表讀取資料,因此直接使用字典結構作為欄位目錄的情況不常見;另外,可與IT_FIELDCAT混合使用,手動的IT_FIELDCAT級別優先
  • I_BACKGROUND_ID = ’ '設定報表背景圖片?
  • I_GRID_TITLE = ALV標題名
  • I_GRID_SETTINGS =設定(列印、網格中的資料同步更新到輸出資料內表)
  • IS_LAYOUT = ALV Layout
  • IT_FIELDCAT = FieldCat配置
  • IT_EXCLUDING =
  • IT_SPECIAL_GROUPS =
  • IT_SORT =
  • IT_FILTER =
  • IS_SEL_HIDE =
  • I_DEFAULT = 'X’使用者是否可以設定預設的佈局變式(即是否可以將某個佈局變式設定為預設的佈局): ‘X’ 可以定義預設佈局,SPACE 不可以定義預設佈局image003[6]
  • I_SAVE = ’ '儲存表格佈局:‘X’ 只能儲存為全域性標準變式,‘U’ 只能儲存特定使用者變式,'A’都可以儲存,SPACE不能儲存變式
  • IS_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 =需要顯示的資料內表
  • EXCEPTIONS
  • PROGRAM_ERROR = 1
  • OTHERS = 2

CALLFUNCTION’REUSE_ALV_LIST_DISPLAY’

  • EXPORTING

  • I_INTERFACE_CHECK = ’ ’

  • I_BYPASSING_BUFFER =

  • I_BUFFER_ACTIVE = ’ ’

  • I_CALLBACK_PROGRAM = ’ ’

  • I_CALLBACK_PF_STATUS_SET = ’ ’

  • I_CALLBACK_USER_COMMAND = ’ ’

  • I_STRUCTURE_NAME =

  • IS_LAYOUT =

  • IT_FIELDCAT =

  • IT_EXCLUDING =

  • IT_SPECIAL_GROUPS =

  • IT_SORT =

  • IT_FILTER =

  • IS_SEL_HIDE =

  • I_DEFAULT = ‘X’

  • I_SAVE = ’ ’

  • IS_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

  • IR_SALV_LIST_ADAPTER =

  • IT_EXCEPT_QINFO =

  • I_SUPPRESS_EMPTY_DATA = ABAP_FALSE

  • IMPORTING

  • E_EXIT_CAUSED_BY_CALLER =

  • ES_EXIT_CAUSED_BY_USER =
    TABLES
    t_outtab =

  • EXCEPTIONS

  • PROGRAM_ERROR = 1

  • OTHERS = 2

image004[6]

簡單例項

TYPE-POOLS:slis.
DATA: fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE.

DATA:BEGIN OF lt_stock OCCURS 0,
sel,"用來做選擇按鈕列
checkbox,"用作複選框列
werks LIKE mard-werks,"工廠
matnr LIKE mara-matnr,"物料
labst LIKE mard-labst,"庫存
int TYPE i,"用來測試統計的自定義欄位
color(4),"用來儲存顏色
END OF lt_stock.

INITIALIZATION.
PERFORM inital.

START-OF-SELECTION.
DEFINE fill_fdcat.
clear fieldcat.
fieldcat-fieldname = &1. "需要顯示的內錶行結構中的哪個欄位
fieldcat-seltext_l = &2. "ALV顯示時標題欄中的文字
fieldcat-key = &3. "是否是關鍵欄位,如果是則單元格顯示的顏色會不同,並會靠前顯示
append fieldcat.
END-OF-DEFINITION.

fill_fdcat ‘WERKS’ ‘工廠’ ‘X’.
fill_fdcat ‘MATNR’ ‘物料’ ‘X’.
fill_fdcat ‘LABST’ ‘庫存’ ‘’.
fill_fdcat ‘INT’ ‘自定義欄位’ ‘’.

CALL FUNCTION ‘REUSE_ALV_GRID_DISPLAY’
EXPORTING
it_fieldcat = fieldcat[]
TABLES
t_outtab = lt_stock.

FORM inital .
lt_stock-sel = ‘X’.
lt_stock-checkbox = ‘X’.
lt_stock-werks = ‘1001’.
lt_stock-matnr = ‘1001M1’.
lt_stock-labst = 4.
lt_stock-int = 2.
lt_stock-color = ‘C100’.
APPEND lt_stock .

CLEAR:lt_stock.
lt_stock-sel = ‘X’.
lt_stock-werks = ‘1001’.
lt_stock-matnr = ‘1001M2’.
lt_stock-labst = 3.
lt_stock-int = 1.
lt_stock-color = ‘C200’.
APPEND lt_stock .

CLEAR:lt_stock.
lt_stock-checkbox = ‘X’.
lt_stock-werks = ‘1002’.
lt_stock-matnr = ‘1001M1’.
lt_stock-labst = 2.
lt_stock-int = 3.
lt_stock-color = ‘C300’.
APPEND lt_stock .

CLEAR:lt_stock.
lt_stock-werks = ‘1002’.
lt_stock-matnr = ‘1001M2’…
lt_stock-labst = 1.
lt_stock-int = 1.
lt_stock-color = ‘C300’.
APPEND lt_stock .
ENDFORM.

image005[6]

Fieldcat動態建立

通過程式設計建立

注:通過此種方式實現時,顯示內表中的所有列都會輸出,只是那些沒有參照字典中的型別欄位沒有欄位標題名而已,這需要在FieldCat生產後,通過程式碼修改即可。

REPORT zalv_test.
TYPE-POOLS:slis.
DATA: fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE.
DATA: layout TYPE slis_layout_alv.

DATA:BEGIN OF lt_stock OCCURS 0,
sel,"用來做選擇按鈕列
checkbox,"用作複選框列
werks LIKE mard-werks,"工廠
matnr LIKE mara-matnr,"物料
labst LIKE mard-labst,"庫存
int TYPE i,"用來測試統計的自定義欄位
color(5),"用來儲存顏色
END OF lt_stock.

INITIALIZATION.
PERFORM inital.

START-OF-SELECTION.
PERFORM build_fieldcat.

CALL FUNCTION ‘REUSE_ALV_GRID_DISPLAY’
EXPORTING
it_fieldcat = fieldcat[]
TABLES
t_outtab = lt_stock.

FORM build_fieldcat .
DATA: descr_ref TYPE REF TO cl_abap_structdescr.
FIELD-SYMBOLS: <comp_output> TYPE abap_compdescr.

DATA: absname TYPE string.
DATA: ref_datadesrc TYPE REF TO cl_abap_datadescr.

DATA: BEGIN OF title ,
rollname TYPE dd04l-rollname,
scrtext_s TYPE dd04t-scrtext_s,
scrtext_m TYPE dd04t-scrtext_m,
scrtext_l TYPE dd04t-scrtext_l,
END OF title.

"lt_stock為帶表頭的內表,這裡傳遞的是表頭,在使用時修改這裡即可
descr_ref ?= cl_abap_typedescr=>describe_by_data( lt_stock ).

LOOP AT descr_ref->components ASSIGNING <comp_output>.

ref_datadesrc  = descr_ref->get_component_type( <comp_output>-name ).
absname = ref_datadesrc->absolute_name.

SPLIT absname AT `=` INTO absname absname.

CLEAR:title.
SELECT SINGLE dd04l~rollname dd04t~scrtext_s dd04t~scrtext_m  dd04t~scrtext_l
    INTO CORRESPONDING FIELDS OF title
    FROM dd04l INNER JOIN dd04t ON dd04l~rollname = dd04t~rollname
    WHERE ddlanguage = sy-langu AND dd04l~rollname = absname.

fieldcat-fieldname = <comp_output>-name.
  • 如果fieldcat定義為:data: fieldcat type table of lvc_s_fcat(不過此時不能再使用REUSE_ALV_GRID_DISPLAY函數了,還是使用以LVC結尾的REUSE_ALV_GRID_DISPLAY_LVC函式,否則引數型別不匹).使用下面語句:

  • fieldcat-reptext = title-scrtext_l.

  • fieldcat-scrtext_l = title-scrtext_l.

  • fieldcat-scrtext_m = title-scrtext_m.

  • fieldcat-scrtext_s = title-scrtext_s.

  • 如果fieldcat定義為:data: fieldcat type slis_t_fieldcat_alv with header line.使用下面語句進行設定:
    fieldcat-seltext_l = title-scrtext_l.
    fieldcat-seltext_m = title-scrtext_m.
    fieldcat-seltext_s = title-scrtext_s.

    APPEND fieldcat.
    ENDLOOP.
    ENDFORM. "build_fieldcatalog

FORM inital .
lt_stock-sel = ‘X’.
lt_stock-checkbox = ‘X’.
lt_stock-werks = ‘1001’.
lt_stock-matnr = ‘1001M1’.
lt_stock-labst = 4.
lt_stock-int = 2.
lt_stock-color = ‘C100’.
APPEND lt_stock .

CLEAR:lt_stock.
lt_stock-sel = ‘X’.
lt_stock-werks = ‘1001’.
lt_stock-matnr = ‘1001M2’.
lt_stock-labst = 3.
lt_stock-int = 1.
lt_stock-color = ‘C200’.
APPEND lt_stock .

CLEAR:lt_stock.
lt_stock-checkbox = ‘X’.
lt_stock-werks = ‘1002’.
lt_stock-matnr = ‘1001M1’.
lt_stock-labst = 2.
lt_stock-int = 3.
lt_stock-color = ‘C300’.
APPEND lt_stock .

CLEAR:lt_stock.
lt_stock-werks = ‘1002’.
lt_stock-matnr = ‘1001M2’…
lt_stock-labst = 1.
lt_stock-int = 1.
lt_stock-color = ‘C300’.
APPEND lt_stock .

ENDFORM.

image006[6]

通過REUSE_ALV_FIELDCATALOG_MERGE函式建立

TYPE-POOLS:slis.
DATA: fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE.
DATA: layout TYPE slis_layout_alv.

"注:如果是參照字典中的structure, table, view中的某個欄位時,欄位的定義只能使用
"LIKE操作符,否則使用TYPE時,該欄位在使用 REUSE_ALV_FIELDCATALOG_MERGE
"函式時將被忽略,但不參照字典型別的除外。另外,內表本身的定義只能採用老式方式
"來定義,不能採用新方式定義,否則不能被REUSE_ALV_FIELDCATALOG_MERGE找到
DATA:BEGIN OF T_STOCK OCCURS 0,
sel,"用來做選擇按鈕列
checkbox,"用作複選框列
werks LIKE mard-werks,"工廠
matnr LIKE mara-matnr,"物料
labst LIKE mard-labst,"庫存
int TYPE i,"用來測試統計的自定義欄位
color(5),"用來儲存顏色
END OF T_STOCK.

INITIALIZATION.
PERFORM inital.

START-OF-SELECTION.
*REUSE_ALV_FIELDCATALOG_MERGE函式內部實現規則:
*

  • 資料型別為 clnt 字典型別欄位不是顯示,即 fieldcat-no_out = space ,如果

  • 需要顯示,則可以設定REUSE_ALV_FIELDCATALOG_MERGE引數i_client_never_display

  • 來顯示

  • 如果參照的字典structure, table, view型別中的某欄位是關鍵字然,則會設定

  • fieldcat-key = ‘X’

  • dictionary references to unit fields are copied if the reference

  • fields are in the structure.
    CALL FUNCTION ‘REUSE_ALV_FIELDCATALOG_MERGE’
    EXPORTING
    i_program_name = sy-repid
    i_inclname = sy-repid"一般指定為本程式名,如果顯示內表參照的為字典中的型別則可省略
    i_internal_tabname = ‘T_STOCK’ "顯示輸出內表名,要大小
    "如果定義的顯示輸出內表是參照的字典中的structure, table, view時,才需要指定

  • i_structure_name   =
    i_client_never_display = 'X'"型別為CLNT字典型別的欄位將不會被設定,即不會顯示
    i_bypassing_buffer = 'X'"另外,此函式還有快取問題,發現在修改輸出內表顯示結構後,此函式不會重新整理,加了以下這兩個引數還是一樣,只能將顯示輸出內表的變數名修改一下,不知道如何做才好啊
    i_buffer_active = ' '
    

    CHANGING
    ct_fieldcat = fieldcat[].

    CALL FUNCTION ‘REUSE_ALV_GRID_DISPLAY’
    EXPORTING
    it_fieldcat = fieldcat[]
    TABLES
    t_outtab = T_STOCK.

FORM inital .
T_STOCK-sel = ‘X’.
T_STOCK-checkbox = ‘X’.
T_STOCK-werks = ‘1001’.
T_STOCK-matnr = ‘1001M1’.
T_STOCK-labst = 4.
T_STOCK-int = 2.
T_STOCK-color = ‘C100’.
APPEND T_STOCK .

CLEAR:T_STOCK.
T_STOCK-sel = ‘X’.
T_STOCK-werks = ‘1001’.
T_STOCK-matnr = ‘1001M2’.
T_STOCK-labst = 3.
T_STOCK-int = 1.
T_STOCK-color = ‘C200’.
APPEND T_STOCK .

CLEAR:T_STOCK.
T_STOCK-checkbox = ‘X’.
T_STOCK-werks = ‘1002’.
T_STOCK-matnr = ‘1001M1’.
T_STOCK-labst = 2.
T_STOCK-int = 3.
T_STOCK-color = ‘C300’.
APPEND T_STOCK .

CLEAR:T_STOCK.
T_STOCK-werks = ‘1002’.
T_STOCK-matnr = ‘1001M2’…
T_STOCK-labst = 1.
T_STOCK-int = 1.
T_STOCK-color = ‘C300’.
APPEND T_STOCK .
ENDFORM.

image007[6]

自定義ALV工具條

預設輸出的ALV已供了很多標準的按鈕了:

image008[6]

image009[6]

自定義ALV工具欄有兩種方式:第一處是自已建立一個GUI Status(通常作法是從SLVC_FULLSCREEN函式組中的拷貝STANDARD_FULLSCREENGui Status,再在此基礎之上新增按鈕即可);第二種是呼叫系統已定義好的標準ALV工具欄;

系統已定義好的標準ALV GUI Status 在程式SAPLKKBL中,可以通過SET PF-STATUS … OF PROGRAM語句直接來呼叫,如:

SET PF-STATUS ‘STANDARD_FULLSCREEN’ OF PROGRAM ‘SAPLKKBL’.

SAPLKKBL程式中定義的系統標準的ALV GUI Status有以下幾種:

l STDPOPBX_FULLSCREEN

l STDPOPUP_FULLSCREEN

l STANDARD_FULLSCREEN 與SLVC_FULLSCREEN函式組中的STANDARD_FULLSCREEN是一樣的,都是標準的(函式組SALV中的STANDARDstatus也是標準的)

l STDPOPBX_FULLSCREEN

l STDPOPUP_FULLSCREEN

l STANDARD_FULLSCR_HR

l STDPOPBX_FS_LIGHT

l STDPOPUP_FS_LIGHT

l STD_LIGHT_FULLSCREEN

這些工具條中的按鈕都已經設定了Function Code,且都是保留字,這些Funcode都已經在ALV Guid控制元件中實現,不需得新分配Funcode功能程式碼,按鈕預設功能碼:

image010[6]

image011[6]

ALV中自定義工具欄需要通過REUSE_ALV_GRID_DISPLAY函式的I_CALLBACK_PF_STATUS_SET引數,傳遞設定GUI Status的Form的名稱,在此Form使用SET PF-STATUS語句來重新定義ALV工具欄,該Form介面如下:
FORM set_pf_status USING rt_extab TYPE slis_t_extab

rt_extab是要排除掉的按鈕,根據Funcode來排除。另外,也可以通過REUSE_ALV_GRID_DISPLAY函式IT_EXCLUDING內表引數來直接排除哪些預置按鈕不可用,IT_EXCLUDING內表結構只有一個fcode欄位,即根據保留的FunCode即可disabled掉。

CALL FUNCTION ‘REUSE_ALV_GRID_DISPLAY’
EXPORTING
i_callback_program = sy-repid
it_fieldcat = fieldcat[]
I_CALLBACK_PF_STATUS_SET = ‘SET_PF_STATUS’
TABLES
t_outtab = t_stock1.

FORM set_pf_status USING rt_extab TYPE slis_t_extab.
"去啟用Function code為&ETA的詳情按鈕
APPEND ‘&ETA’ TO rt_extab.
SET PF-STATUS ‘STANDARD_FULLSCREEN’ OF PROGRAM ‘SAPLKKBL’ EXCLUDING
rt_extab.
ENDFORM.

如果沒有重定義ALV工具欄,則會預設使用函式組SLVC_FULLSCREEN中定義的STANDARD_FULLSCREEN工具條

快速拷貝GUI Status

在自定義工具欄時,通常從標準GUI Status上拷貝出來,再新加按鈕。

函式組 SLVC_FULLSCREEN中定義的STANDARD_FULLSCREEN GUI Status拷貝方式如下,通過 SE41可以快速拷貝:

image012[6]

如果不是ALV,是Write輸出時,拷貝:

image013[6]

ALV事件

ALV觸發的事件(如雙擊某行資料、單擊熱點、點ALV工具欄上的自定義的按鈕時),會回撥I_CALLBACK_USER_COMMAND引數指定的Form,介面如下:

FORM user_command USING r_ucomm LIKE sy-ucomm
rs_selfield TYPE slis_selfield.

Parameter R_UCOMM 為觸發的function code

結構 RS_SELFIELD 包括了以下欄位:

tabname : Name of the internal output table 輸出內表名
tabindex : Index of the internal output table 資料行索引
fieldname: Field name 游標所在單元格所對應的的欄位名
endsum : Cursor is located on the totals line
sumindex : If >0, the cursor is located on a subtotals line
value : Value of the field on the list 游標所在單元格的值
refresh : (Exporting) List should be set up again為X時,當用戶在顯式介面上對資料進行修改時,同時內表中的資料也隨之重新整理
col_stable:(Exporting) Keep column position when list is set up again
row_stable:(Exporting) Keep row position when list is set up again
exit :(Exporting) Exit list (and ALV)
before_action: Call before standard action execution
after_action : Call after standard action execution, before list setup
CALL FUNCTION ‘REUSE_ALV_GRID_DISPLAY’
EXPORTING
i_callback_program = sy-repid
it_fieldcat = fieldcat[]
I_CALLBACK_USER_COMMAND = ‘USER_COMMAND’
TABLES
t_outtab = gt_data[].
注:只有自已新增的按鈕(或雙擊資料行時、熱點點選)再會呼叫,ALV 標準預設的Function Code是不會呼叫的(除非使用使用IT_EVENT_EXIT)
FORM user_command USING r_ucomm LIKE sy-ucomm
rs_selfield TYPE slis_selfield.
MESSAGE i001(00) WITH ‘事件觸發時當前行:’ rs_selfield-tabindex.
ENDFORM.

所支援事件

ALV可觸發的事件可用REUSE_ALV_EVENTS_GET 函式來獲得,輸出一個內表,型別是slis_t_event,行項為slis_alv_event,包含兩個欄位:一個為事件名,另一個是事件處理的FORM名

DATA: i_events TYPE slis_t_event WITH HEADER LINE.
CALL FUNCTION ‘REUSE_ALV_EVENTS_GET’
EXPORTING
"0:表示獲取的是通過函式REUSE_ALV_LIST_DISPLAY產生的ALV所支援的事件
"4:表示獲取的是通過函式REUSE_ALV_GUID_DISPLAY產生的ALV所支援的事件
i_list_type = 4
IMPORTING
et_events = i_events[].

LOOP AT i_events.
WRITE:/ i_events-name,i_events-form.
ENDLOOP.

image014[6]

觸發USER_COMMAND事件時,會呼叫以下簽名的Form:

觸發PF_STATUS_SET事件時,會呼叫以下簽名的Form(其中pf_status_set名是自定義的,非固定為 pf_status_set):
FORM pf_status_set USING rt_extab TYPE slis_t_extab.

事件名

何時觸發

觸發時所回撥Form的簽名要求

回撥方式

USER_COMMAND

使用者點選工具欄中自定義按鈕、預置按鈕(需通過REUSE_ALV_GRID_DISPLAY函式的IT_EVENT_EXIT引數來特殊處理才會回撥指定的Form)、資料行雙擊、單元格熱點點選等一系列使用者操作

FORM user_command USING r_ucomm LIKE sy-ucomm rs_selfield TYPE slis_selfield.

(其中user_command名是自定義的,而不是固定為 user_command)

  1. 通過REUSE_ALV_GRID_DISPLAY函式的I_CALLBACK_USER_COMMAND引數介面回撥
    
  2. 通過REUSE_ALV_GRID_DISPLAY函式的IT_EVENTS引數介面回撥
    

PF_STATUS_SET

ALV工具欄顯示前,可自定義工具條

FORM pf_status_set USING rt_extab TYPE slis_t_extab

(其中 pf_status_set 名是自定義的,而不是固定為 pf_status_set )

  1.  通過REUSE_ALV_GRID_DISPLAY函式的I_CALLBACK_PF_STATUS_SET引數介面回撥
    
  2.  通過REUSE_ALV_GRID_DISPLAY函式的IT_EVENTS引數介面回撥
    

TOP_OF_PAGE

頁首定製

無引數

通過REUSE_ALV_GRID_DISPLAY函式的IT_EVENTS引數介面回撥

更多事件詳細介紹可參考REUSE_ALV_GRID_DISPLAY函式的IT_EVENTS引數文件說明
image015[6]

image016[6]
types: slis_t_event type slis_alv_event occurs 0.
*— Structure for event handling
types: begin of slis_alv_event,
name(30),"事件名
form(30),"事件觸發時需回撥的Form名
end of slis_alv_event.

工具條預置按鈕回調出口IT_EVENT_EXIT

點選ALV預設提供的工具欄按鈕時,不會回撥I_CALLBACK_USER_COMMAND = 'USER_COMMAND’引數中指定的Form ,因為那些按鈕所對應的功能程式碼已被設為保留Funcode了,如果要想在點選這些標準的按鈕時也回撥指定的Form,可通過REUSE_ALV_GRID_DISPLAY函式的IT_EVENT_EXIT 引數實現的,可以向IT_EVENT_EXIT引數內表填充需要被攔截的保留Funcode,及在是執行對應功能程式碼之前還是之後呼叫,具體應用請參考這裡:

DATA: event_exit TYPE slis_t_event_exit WITH HEADER LINE.
event_exit-ucomm = ‘&OAD’."此Funcode為點選AlV工具欄上的選擇佈局按鈕時image017[6]會被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.

顏色

注意:

顏色設定中有優先順序順序,他們是單元格–>行–>列,即若同時使用了上述3中更改顏色的方法,則列的顏色會被行的顏色覆蓋掉,而行的顏色又會被單元格的顏色覆蓋掉,最終只會顯示出單元格的顏色。

如果這列被設定為關鍵列,就是LS_FCAT-KEY = ‘X’ ,那麼顏色設定就不會起作用
行顏色

ALV中的每行資料顏色是通過LayOut來控制的。需要在顯示輸出內表結構中增加一列欄位,用來儲存資料行的顏色

TYPE-POOLS:slis.
DATA: gt_fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE.
DATA: gs_layout TYPE slis_layout_alv.

DATA:BEGIN OF gt_data OCCURS 0,
val1(4),"顏色值
val2(4),"顏色值
color(4),"用來儲存行顏色
END OF gt_data.

START-OF-SELECTION.
PERFORM inital.
DEFINE fill_fdcat.
clear gt_fieldcat.
gt_fieldcat-fieldname = &1.
gt_fieldcat-seltext_l = &2.
append gt_fieldcat.
END-OF-DEFINITION.

fill_fdcat ‘VAL1’ ‘顏色值’.
fill_fdcat ‘VAL2’ ‘顏色值’.

gs_layout-info_fieldname = ‘COLOR’." 指定哪一列用來作為行顏色的列
CALL FUNCTION ‘REUSE_ALV_GRID_DISPLAY’
EXPORTING
it_fieldcat = gt_fieldcat[]
is_layout = gs_layout
TABLES
t_outtab = gt_data.

FORM inital .
DATA: c1,c2,c3.
DO 8 TIMES.
c1 = sy-index - 1.
DO 2 TIMES.
c2 = sy-index - 1.
DO 2 TIMES.
c3 = sy-index - 1.
CONCATENATE ‘C’ c1 c2 c3 INTO gt_data-color.
gt_data-val1 = gt_data-color.
gt_data-val2 = gt_data-color.
APPEND gt_data.
ENDDO.
ENDDO.
ENDDO.
ENDFORM.

顏色值定義為4位字元,首位固定為字母“C”,第2位為顏色,由0~7表示,不同的數字表示不同的顏色屬性,如:

0 = background color 1 = Gray-blue 2 = Light gray 3 = yellow

4 = blue-gray 5 = green 6 = red 7 = orange

第3位表示輸出文字是否高亮顯示,由01表示,為1時表示高亮顯示。第4位測試了一下,基本上09顏色都差不多,唯一就是當取值為1時,底色又回到了灰色(且只是在第3位為0時才有此效果)。

ALV中的顏色是由4位陣列成:‘C’+COL+INT+INV

*** Structure for colors
types: begin of slis_color,
col type i,
int type i,
inv type i,
end of slis_color.

第1位:固定取值為C

第2位COL:顏色值,取值為0~7

第3位INT:高亮,即顏色是否加深,取值為0、1。1表示加深顯示

第4位INV:顏色是否反轉,即顏色是作用在背景上,還是作用在輸出字元上,取值上為0、1。為1時表示設定的是前景色,即輸出字元本身的顏色(好像只有在第3位為0時才有效?)

以下是各種顏色值測試表:

image018[6]image019[6]image020[6]image021[6]

image022[6]image023[6]image024[6]image025[6]

image026[6]image027[6]

列顏色

image028[6]

TYPE-POOLS:slis.
DATA: gt_fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE.
DATA: gt_sort TYPE slis_t_sortinfo_alv WITH HEADER LINE.
DATA:BEGIN OF gt_data OCCURS 0,
curr TYPE ekpo-netpr,
int TYPE i,
p TYPE p LENGTH 5 DECIMALS 2,
END OF gt_data.

START-OF-SELECTION.
PERFORM inital.
DEFINE fill_fdcat.
clear gt_fieldcat.
gt_fieldcat-fieldname = &1.
gt_fieldcat-seltext_l = &2.
if &1 = ‘CURR’ .
"設定列顏色
gt_fieldcat-emphasize = ‘C510’.
endif.
if &1 = ‘INT’ .
gt_fieldcat-emphasize = ‘C610’.
endif.
append gt_fieldcat.
END-OF-DEFINITION.

fill_fdcat ‘CURR’ ‘CURR’ .
fill_fdcat ‘INT’ ‘INT’ .
fill_fdcat ‘P’ ‘P(3.2)’ .

CALL FUNCTION ‘REUSE_ALV_GRID_DISPLAY’
EXPORTING
i_callback_program = sy-repid
it_fieldcat = gt_fieldcat[]
TABLES
t_outtab = gt_data[].

FORM inital .
gt_data-curr = 1.
gt_data-int = 1.
gt_data-p = 1.
APPEND gt_data.
gt_data-curr = 2.
gt_data-int = 2.
gt_data-p = 2.
APPEND gt_data.
ENDFORM.

單元格顏色

除了可為整行設定行顏色外,每個單元格(不只是整列)的顏色也是可以單獨進行設定。當然既然可以給單元格設定顏色,則整列相同顏色也是可以採用此方式來設定的

image029[6]

TYPE-POOLS:slis.
DATA: gt_fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE.
DATA: gs_layout TYPE slis_layout_alv.

DATA:BEGIN OF gt_data OCCURS 0,
val1(40),"顏色值
val2(40),"顏色值
val3(40),
colortable TYPE slis_t_specialcol_alv, "每行中的單元格顏色內表,可對多個單元格進行不同顏色設定
END OF gt_data.
"每行中單元格顏色列表
DATA: gt_color TYPE slis_t_specialcol_alv WITH HEADER LINE.

START-OF-SELECTION.
PERFORM inital.
DEFINE fill_fdcat.
clear gt_fieldcat.
gt_fieldcat-fieldname = &1.
gt_fieldcat-seltext_l = &2.
append gt_fieldcat.
END-OF-DEFINITION.

fill_fdcat ‘VAL1’ ‘顏色值’.
fill_fdcat ‘VAL2’ ‘顏色值’.
fill_fdcat ‘VAL3’ ‘無顏色’.

gs_layout-coltab_fieldname = ‘COLORTABLE’."設定輸出內表中哪列為顏色列表

CALL FUNCTION ‘REUSE_ALV_GRID_DISPLAY’
EXPORTING
it_fieldcat = gt_fieldcat[]
is_layout = gs_layout
TABLES
t_outtab = gt_data.

FORM inital .
DATA: c1,c2.
DO 7 TIMES.
c1 = gt_color-color-col = sy-index - 1."顏色值
DO 2 TIMES.
c2 = gt_color-color-int = sy-index - 1."顏色亮度
gt_color-color-inv = ‘0’."顏色作用於背景
CASE sy-index .
WHEN 1.
gt_color-fieldname = ‘VAL1’."需進行顏色設定的列名(已具體到單元格)
CONCATENATE ‘col=’ c1 ‘int=’ c2 ‘inv=0’ INTO gt_data-val1 .
WHEN 2.
gt_color-fieldname = ‘VAL2’."需進行顏色設定的列名(已具體到單元格)
CONCATENATE ‘col=’ c1 ‘int=’ c2 ‘inv=0’ INTO gt_data-val2 .
ENDCASE.
APPEND gt_color.
ENDDO.
"設定每行資料中單元格的顏色內表
gt_data-colortable = gt_color[].
gt_data-val3 = ‘無顏色’.
APPEND gt_data.
CLEAR:gt_color,gt_color[].
ENDDO.
ENDFORM.

可編輯

可以通過layout(slis_layout_alv)中的edit引數來設定整個網格(所有單元格)是否可編輯:

DATA: gs_layout TYPE slis_layout_alv.
gs_layout-edit = ‘X’.

如果只想讓某列(一整列)可修改,而不是整個網格,則可對fieldcat中的edit引數來設定某列是否可編輯:

DATA: gt_fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE.
gt_fieldcat-edit = ‘X’.

如果想對某些單元格進行設定,在滿足一定條件的單元格才能修改,此時只能使用以LVC結尾的REUSE_ALV_GRID_DISPLAY_LVC函式,而非REUSE_ALV_GRID_DISPLAY函式:

"TYPE-POOLS:slis.
DATA: gt_fieldcat TYPE lvc_t_fcat WITH HEADER LINE."注:此時的fieldcat不再引用slis_t_fieldcat_alv型別
DATA: gs_layout TYPE lvc_s_layo."注:此時的Layout不再是引用slis_layout_alv型別

DATA:BEGIN OF gt_data OCCURS 0,
val1(40),
val2(40),
cellstab TYPE lvc_t_styl,"單元格可編輯控制
END OF gt_data.
"單元格可編輯控制內表
DATA: gt_cellstab TYPE lvc_t_styl WITH HEADER LINE.

START-OF-SELECTION.
PERFORM inital.
DEFINE fill_fdcat.
clear gt_fieldcat.
gt_fieldcat-fieldname = &1.
gt_fieldcat-scrtext_l = &2.
"設定單元格為可編輯狀態:此處設定所有單元格都可編輯
gt_fieldcat-edit = ‘X’.
append gt_fieldcat.
END-OF-DEFINITION.

fill_fdcat ‘VAL1’ ‘列1’.
fill_fdcat ‘VAL2’ ‘列2’.

gs_layout-stylefname = ‘CELLSTAB’."設定可編輯資訊
CALL FUNCTION ‘REUSE_ALV_GRID_DISPLAY_LVC’
EXPORTING
is_layout_lvc = gs_layout
it_fieldcat_lvc = gt_fieldcat[]
TABLES
t_outtab = gt_data.

FORM inital .
gt_data-val1 = ‘cell1’.
gt_data-val2 = ‘cell2’.
gt_cellstab-fieldname = ‘VAL1’.
"將原本可編輯的單元格切換到不可編輯樣式。注:這裡
"只是樣式的切換,不能僅僅使用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[].
APPEND gt_data.
ENDFORM.