
两个函数都可以将数据以ALV的形式显示出来。两个函数都要用到的全局变量为:类型池SLIS.
REUSE_ALV_GRID_DISPLAY用到的全局变量如下:
DATA: wa_fieldcat TYPE slis_fieldcat_alv , " 相当于工作区
i_fieldcat TYPE slis_t_fieldcat_alv , " 存放列名的内表
i_layout TYPE slis_layout_alv . " 负责整个ALV的全局属性
REUSE_ALV_GRID_DISPLAY_LVC用到的全局变量如下:
DATA: wa_fieldcat TYPE lvc_s_fcat , " 相当于工作区
i_fieldcat TYPE lvc_t_fcat , " 存放列名的捏表
i_layout TYPE lvc_s_layo . " 负责整个ALV的全局属性
在子程序中指定需要显示的字段(build fieldcat)
FORM frm_fcatset TABLES t_fcat TYPE lvc_t_fcat
USING u_fieldname
u_ref_table
u_ref_field
u_seltext
u_key
u_do_sum
u_decimals_o
u_emphasize
u_no_out
u_just
u_outlen.
DATA:lwa_fcat TYPE lvc_s_fcat.
lwa_fcat-fieldname = u_fieldname.
lwa_fcat-ref_table = u_ref_table.
lwa_fcat-ref_field = u_ref_field.
lwa_fcat-seltext = u_seltext.
lwa_fcat-selddictxt = 'R'.
lwa_fcat-reptext = u_seltext.
lwa_fcat-key = u_key.
lwa_fcat-do_sum = u_do_sum. “求和
lwa_fcat-decimals_o = u_decimals_o.
lwa_fcat-emphasize = u_emphasize.
lwa_fcat-no_out = u_no_out.
wa_fcat-just = u_just. “L左对齐C居中对齐R右对齐
lwa_fcat-outputlen = u_outlen.
lwa_fcat-scrtext_m = u_seltext.
lwa_fcat-colddictxt = 'M'.
wa_fieldcat-col_opt = 'X' 单列优化宽度
APPEND lwa_fcat TO t_fcat.
CLEAR lwa_fcat.
ENDFORM.
当然,在不指明对其方式的前提下,ABAP的各种数据类型优默认的对其方式,其中字符串是默认为左对齐,而货币、数量默认为右对齐;
在子程序中设置ALV的全局属性(build layout)
i_layout_lvc-zebra = 'X' . " 使ALV界面呈现颜色交替
i_layout_lvc-sel_mode = 'A' . " 选择模式,“A”在最左端有选择按钮
i_layout_lvc-cwidth_opt = 'X' . " 自动优化列宽
i_layout_lvc-detailinit = 'X' . " 是否出现细节屏幕
i_layout_lvc-detailtitl = '详细内容' . " 细节屏幕标题
如果此时在子FORM(F_BUILD_LAYOUT)里添加下列属性,则求和后的行就会在第一行出现:
i_layout-totals_bef = 'X' .
在子程序中将内表中的数据进行显示(Display)
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
i_callback_program = sy-repid " 当前程序
is_layout_lvc = i_layout_lvc " 属性内表
it_fieldcat_lvc = i_fieldcat_lvc[] " 列明内表
i_save = 'A' " 是否保存布局
TABLES
t_outtab = i_tab " 数据内表
EXCEPTIONS
program_error = 1
OTHERS = 2.
为ALV程序添加表头标题(HTML表头)
在显示ALV的函数REUSE_ALV_GRID_DISPLAY_LVC中添加一个参数:
i_callback_html_top_of_page = 'FRM_TOP_OF_PAGE'
其中F_TOP_OF_PAGE是书写ALV表头标题的子程序,这里只是使用,没有明显的PERFORM调用,如下:
FORM frm_top_of_page USING p_cl_dd TYPE REF TO cl_dd_document.
FORM FRM_TOP_OF_PAGE USING CL_DD TYPE REF TO CL_DD_DOCUMENT.
DATA: LC_P TYPE I,
LC_BUFF TYPE STRING.
CONCATENATE '
| ' gc_title ' |
CALL METHOD CL_DD->HTML_INSERT
EXPORTING
CONTENTS = LC_BUFF
CHANGING
POSITION = LC_P.
ENDFORM.
例:
" 开始输出表头标题
m_buffer = '
CALL METHOD p_cl_dd->html_insert
EXPORTING
contents = m_buffer
CHANGING
position = m_p.
" 输出制表人和制表日期
CONCATENATE '
出表人:' l_name
'                   '
'                  '
'                  '
'                  '
'                  '
'                  '
'出表日期:' l_date INTO m_buffer .
CALL METHOD p_cl_dd->html_insert
EXPORTING
contents = m_buffer
CHANGING
position = m_p.
为ALV输出内表排序
在排序之前,如果用一列有相同的数据,则排好序以后,在该列会自动将想用的数据合并为一行显示,不再出现多行重复的情况,但是若该ALV中有字段设置了“可编辑”,合并这一现象会失效,步骤如下:
在显示ALV的子程序里定义排序用到的变量:
" 定义排序变量
DATA: wa_sort_lvc TYPE lvc_s_sort ,
it_sort_lvc TYPE lvc_t_sort .
在ALV输出函数中添加排序的属性:
it_sort_lvc = it_sort_lvc
设置好需要排序的字段:
" 设置排序参数
wa_sort_lvc-spos = 1 . " 排序顺序
wa_sort_lvc-fieldname = 'CITYFROM' . " 排序字段
wa_sort_lvc-up = 'X' . " 升序
APPEND wa_sort_lvc TO it_sort_lvc .
CLEAR wa_sort_lvc .
wa_sort_lvc-spos = 2 . " 排序顺序
wa_sort_lvc-fieldname = 'CITYTO' . " 排序字段
wa_sort_lvc-up = 'X' . " 升序
APPEND wa_sort_lvc TO it_sort_lvc .
CLEAR wa_sort_lvc .
例:
PERFORM frm_sort_build TABLES lit_sort
USING '1' 'RSNUM' 'X' '' '' 'X' ''.
FORM FRM_FCATSET TABLES t_fcat TYPE lvc_t_fcat
USING u_fieldname "列名
u_seltext "列名
u_key "关键字段
u_do_sum "总计
u_decimals_o "输出小数位的编号
u_emphasize "带有颜色的高亮列
u_no_out "列没有输出
u_just "对齐
u_outlen. "输出长度
DATA:lwa_fcat TYPE lvc_s_fcat.
lwa_fcat-fieldname = u_fieldname.
lwa_fcat-seltext = u_seltext.
lwa_fcat-reptext = u_seltext.
lwa_fcat-key = u_key.
lwa_fcat-do_sum = u_do_sum.
lwa_fcat-decimals_o = u_decimals_o.
lwa_fcat-emphasize = u_emphasize.
lwa_fcat-no_out = u_no_out.
lwa_fcat-just = u_just.
lwa_fcat-outputlen = u_outlen.
lwa_fcat-scrtext_m = u_seltext.
APPEND lwa_fcat TO t_fcat.
CLEAR: lwa_fcat.
ENDFORM.
隐藏不必要的标准按钮
现在ALV的子程序里定义隐藏按钮用到的变量:
" 定义隐藏标准按钮的变量
DATA: wa_excluding TYPE slis_t_extab ,
it_excluding TYPE slis_extab .
得到需要隐藏的标准按钮的“FCODE”
用事务码“SE24”进入SAP的“类别制作器”,在“Object Type”后面输入ALV类的“CL_GUI_ALV_GRID”,点击“Display”进入显示界面,点击“Attributes”选项卡,找到自己需要的“属性”和“初始值”,这个初始值就是我们需要找的标准按钮的“FCODE”。
将需要隐藏的标准按钮的“FCODE”添加到内表IT_EXCLUDING中,代码如下:
" 设置要隐藏的按钮的“FCODE”
wa_excluding-fcode = '&ABC' .
APPEND wa_excluding TO it_excluding .
在显示ALV的函数的输入参数里添加隐藏按钮的属性参数:
it_excluding = it_excluding
自定义工具栏
在显示ALV的函数里输入参数里指定自定义按钮的子程序
i_callback_pf_status_set = 'F_SET_STATUS'
该子程序和表头产生的子程序一样,也不是显示调用,代码如下:
FORM f_set_status USING p_extab TYPE slis_t_extab .
SET PF-STATUS 'Z_ALV_STATUS' .
ENDFORM. " f_set_status
双击其中的“Z_ALV_STATUS”,进入创建工具栏的界面,输入名字后进入最终的界面在界面右侧,点击“应用工具条”后面的展开符号,在“项目”后面的白色方框内输入“自定义按钮”的代码后回车,选择静态文本回车,在“函数文本”后面输入想要显示的按钮的名称,在“图标名称”后面选择相应的图标(可选),回车在这一界面选择一个“快捷键”(必填)后回车,这样一个自定义按钮就做好了,也可以修改,记住刚刚创建的按钮的代码,在下面的捕捉用户的动作的自FORM(F_USER_COMMAND)会根据刚才的代码来进行相应的操作;
1、点开“功能键”后面的展开符号,进入功能键的设置,下图是各个动作对应的代码:
2、没有自定义按钮时候,函数里的“i_callback_pf_status_set = 'F_SET_STATUS'”这个参数可以不要,这时会显示ALV标准的按钮,当然这些按钮可以部分隐藏(见三、2);
3、当我们使用自定义按钮后,ALV自带的标准按钮,就会失效,这时我们需要将一些用户要求我们必须显示的按钮一一地在“应用工具条”后面补上,如下图:
其中“分隔符”的插入方法为:在需要插入分隔符的方框内选择菜单“Edit” “Insert” “Separator line”即可插入分隔符;
下面是上图中的标准工具的名称、代码、图标名称、快捷键
| 名称 | 代码 | 图标名称 | 快捷键 |
| 刷新 | REFRESH | ICON_REFRESH | F8(可随便更改) |
| 导出为EXCEL表格 | EXCEL | 无 | Shift-F8(可随便更改) |
| ABC 分析 | &ABC | ICON_ABC | Ctrl-F1 |
| 按升序排列 | &OUP | ICON_SORT_UP | Ctrl-F4 |
| 设置过滤器 | &ILT | ICON_FILTER | Ctrl-F5 |
| 总计 | &UMC | ICON_SUM | Ctrl-F6 |
| 邮件查收件 | %SL | ICON_MAIL | Ctrl-F7 |
| 更改布局… | &OL0 | ICON_ALV_VARIANTS | Ctrl-F8 |
| 选择布局… | &OAD | ICON_ALV_VARIANT_CHOOSE | Ctrl-F9 |
| 保存布局… | &AVE | ICON_ALV_VARIANT_SAVE | Ctrl-F10 |
| 信息 | &INFO | ICON_INFORMATION | Ctrl-F12 |
| 明细 | &ETA | ICON_SELECT_DETAIL | Ctrl-Shift-F3 |
| 按降序排列 | &ODN | ICON_SORT_DOWN | Ctrl-Shift-F4 |
| 删除过滤器 | &ILD | ICON_FILTER_UNDO | Ctrl-Shift-F5 |
| 小计… | &SUM | ICON_INTERMEDIATE_SUM | Ctrl-Shift-F6 |
| Microsof | &VEXCEL | ICON_XLS | Ctrl-Shift-F7 |
| 字处理 | &AQW | ICON_WORD_PROCESSING | Ctrl-Shift-F8 |
| 本地文件 | %PC | ICON_EXPORT | Ctrl-Shift-F9 |
| 打印预览 | &RNT_PREV | ICON_LAYOUT_CONTROL | Ctrl-Shift-F10 |
| 图形 | &GRAPH | ICON_GRAPHICS | Ctrl-Shift-F11 |
用户动作的捕捉
在ALV的函数的输入参数里指定捕捉用户动作的子FORM:
FORM f_user_command USING p_ucomm TYPE sy-ucomm
p_rs_selfield TYPE slis_selfield .
在“字段和列名”的子FORM(F_FIELDS)里,对需要链接的列添加“热点”属性
v_pos = v_pos + 1 .
wa_fieldcat-col_pos = v_pos .
wa_fieldcat-fieldname = 'CITYFROM' .
wa_fieldcat-scrtext_l = '起飞城市' .
wa_fieldcat-fix_column = 'X' .
wa_fieldcat-hotspot = 'X' . " 热点,链接用
APPEND wa_fieldcat TO i_fieldcat .
CLEAR wa_fieldcat .
这样在显式界面上“起飞城市”所代表的字段“CITYFROM”的下面就会出现一条下划线,同时当鼠标移动到该列时,就会变成“等待”的手势,当用户单击每一条时,就会触动子FORM(F_USER_COMMAND)中的动作,进而引起某些操作;
对于热点链接,所对应的动作码为“&IC1”,在子FORM(F_USER_COMMAND)中捕捉用户的动作,并进行相应的操作,代码如下:
FORM f_user_command USING p_ucomm TYPE sy-ucomm
p_rs_selfield TYPE slis_selfield .
CASE p_ucomm.
WHEN '&IC1' . " 判断用户的动作
" 读取用户点击的当前行的一行内容
READ TABLE i_tab INTO wa_tab INDEX p_rs_selfield-tabindex .
IF p_rs_selfield-fieldname EQ 'CITYFROM'. " 判断用户点击的是哪一列
IF NOT wa_tab-cityfrom IS INITIAL .
PERFORM f_show_detail USING p_rs_selfield . " 显示具体细节
ENDIF.
ELSEIF p_rs_selfield-fieldname EQ 'TCODE' .
IF NOT wa_tab-tcode IS INITIAL .
PERFORM f_call_tran USING p_rs_selfield . " 调用其他事务
ENDIF .
ELSEIF p_rs_selfield-fieldname EQ 'ICON_FOLDER' .
PERFORM f_open_folder USING p_rs_selfield . " 打开文件
ENDIF.
CLEAR wa_tab .
WHEN '&SAVE_DATA' .
PERFORM f_save_data . " 保存数据
WHEN 'PRINT' .
PERFORM f_print_data. " 打印数据
WHEN 'EXCEL' .
PERFORM f_export . " 导出数据
ENDCASE.
p_rs_selfield-refresh = 'X' . " 当用户在显式界面上对数据进行修改时,同时内表中的数据也随之刷新
ENDFORM. " f_user_command
显示具体细节
1>、 先定义一个存放具体内容的内表并整理好相关数据;
2>、 调用 一个指定大小的屏幕来显示具体的内容,代码如下:
CALL SCREEN 0100 STARTING AT 12 12 ENDING AT 137 24 .
3>、 双击该屏幕号码“0100”创建该屏幕,在“属性”卡输入该屏幕的描述,在“逻辑流”卡里将系统默认注释掉的PBO、PAI事件的模块取消注释并产生这两个模块(双击并确定);
4>、 在“屏幕制作器”界面点击进入“屏幕制作器”的图形界面,开始绘制我们需要的屏幕元素,这里我们需要一个“表控制”(最左边从下数第四个元素),该表格的属性设置为:
名称:
起始行列和高宽
上图表示“列标题”为“具体内容”,可以水平或垂直的调节大小,有水平和垂直的分隔符,只能同时选中一行一列,带选择列(DE_BOX),最左端两列固定不滚动;
5>、 接下来给单元格和列标题名称并给单元格指定内表的字段,
6>、 屏幕的PBO、PAI事件的代码如下:
PROCESS BEFORE OUTPUT.
MODULE status_0100.
LOOP AT i_detail INTO wa_detail
WITH CONTROL vs_detail CURSOR i_detail-current_line .
ENDLOOP.
*
PROCESS AFTER INPUT.
LOOP AT i_detail .
ENDLOOP.
MODULE user_command_0100.
7>、 需要在定义变量的时候声明一下表控制和动作的接受者(OK_CODE)如下:
* 表控制IS_MATNR
CONTROLS vs_detail TYPE TABLEVIEW USING SCREEN 0100 .
" 利用同名传递原理,来接受细节屏幕上的元素“ok_code”的值
DATA: ok_code TYPE sy-ucomm .
8>“MODULE status_0100.”的代码如下:
MODULE status_0100 OUTPUT.
SET PF-STATUS '0100' .
DESCRIBE TABLE i_detail LINES vs_detail-current_line .
ENDMODULE. " status_0100 OUTPUT
在“0100”的工具栏里,只设置即可满足需求;
“MODULE user_command_0100.”的代码如下:
MODULE user_command_0100 INPUT.
CASE ok_code.
WHEN 'BACK' .
SET SCREEN 0 . " 返回主屏幕
ENDCASE.
ENDMODULE. " user_command_0100 INPUT
完成调用细节屏幕;
注意:在显示细节屏幕的字段的类型上,当内表中有数据为货币类型的时候,要在“格式”里指明该字段是货币类型的数据,如下图:
调用其他事务(搜索帮助)
FORM f_call_tran USING p_rs_selfield TYPE slis_selfield .
SET PARAMETER ID 'LIB' FIELD p_rs_selfield-value .
CALL TRANSACTION 'SE37' ."AND SKIP FIRST SCREEN .
ENDFORM. " f_call_tran
“LIB”是指参数ID,查找方法:用一个事务码进入事务界面,在输入框内按F1,在弹出来的界面中点击,新界面中的就是参数ID;
“SE37”是指我们要调用的事务代码,“AND SKIP FIRST SCREEN”表示跳过第一屏屏幕;
例:
AT SELECTION-SCREEN ON VALUE-REQUEST FOR S_MBLNR-HIGH.
CALL TRANSACTION 'MB51'.
GET PARAMETER ID 'MBN' FIELD S_MBLNR-HIGH.
打开并选择文件:
先在内表中定义好存放文件路径的字段(这里是FILE_PATH),当用户点击界面上设置好的打开文件图标时,就会触发子FORM(F_USER_COMMAND)里的打开文件的子FORM(F_OPEN_FOLDER);
子FORM(F_OPEN_FOLDER)的代码如下:
FORM f_open_folder USING p_rs_selfield TYPE slis_selfield .
DATA: l_file_path LIKE rlgrap-filename .
CALL FUNCTION 'WS_FILENAME_GET'
EXPORTING
mode = 'O'
title = '选择文件'
IMPORTING
filename = l_file_path
EXCEPTIONS
inv_winsys = 1
no_batch = 2
selection_cancel = 3
selection_error = 4
OTHERS = 5.
IF sy-subrc = 0.
wa_tab-file_path = l_file_path . " 将得到的文件的路径赋给当前行的路径
MODIFY i_tab INDEX wa_tab-numer FROM wa_tab TRANSPORTING file_path .
CLEAR l_file_path .
ELSE .
MESSAGE s000 WITH '没有选择文件' .
ENDIF.
ENDFORM. " f_open_folder
输出图标
1>、首先在开始包含进一个包括,如下:
" 包含图标等在内的一些信息
INCLUDE 2>、然后在内表中定义一个代表图标的字段(这里如ICON_FOLDER),在整理数据的时候,需要将代表图标的代码赋给给字段,如下 " 图标 wa_banfn-icon_folder = icon_object_folder . 3>、接着在子FORM(F_FIELDS)里给需要图标显示的列添加下列属性: v_pos = v_pos + 1 . wa_fieldcat-col_pos = v_pos . wa_fieldcat-fieldname = 'ICON_FOLDER' . wa_fieldcat-scrtext_l = 'ICON' . wa_fieldcat-icon = 'X' . " 图标 wa_fieldcat-hotspot = 'X' . APPEND wa_fieldcat TO i_fieldcat . CLEAR wa_fieldcat . 这样图标就可以在ALV界面中显示了,其中添加“热点”的目的是为了当用户点击该图标的时候,可以触发一系列的操作,如文件的选择等等; 注意:图标的名称用事务码“ICON”进入后左边第二列就是图标代码,根据需要进行选择; 固定列和关键列 两者都可以使具有该属性的列固定不滚动,但是前者不改变该列的颜色,而后者会将该列的颜色弄成一色,不容易确认,但它具有其他的功能,代码如下: wa_fieldcat-fix_column = 'X' . " 固定列 wa_fieldcat-key = 'X' . " 关键列 列的字符宽度 可以明显地指明该列的输出宽度,属性代码如下: wa_fieldcat-outputlen = 10 . " 输出宽度 列抬头的工具提示,在列的属性添加下列参数,当用户将鼠标放到列名上时,可以显示“提示”2字,代码如下: wa_fieldcat-tooltip = '提示' . F1帮助 1>、在子FORM(F_FIELDS)里列的属性添加“数据元素”这一属性,代码如下: wa_fieldcat-rollname = 'PS_PSPID' . " 指定数据元素 就可以在ALV的显示界面将鼠标放到该字段的位置后按F1会弹出该字段的说明; 2>、指定数据元素之后,可以不指明字段的描述(如SCRTEXT_L、SCRTEXT_M、SCRTEXT_S),函数会自动将字段的描述显示,但是没有自己指定的灵活 F4帮助 1>、在子FORM(F_FIELDS)里列的属性添加下列属性,代码如下: wa_fieldcat-ref_field = 'PSPID' . wa_fieldcat-ref_table = 'PROJ' . 这样在ALV的显示界面,在该字段处就可以按F4来查看相关的内容了; 输入并保存、回调修改内表(输入时的小数位错位的问题、指定数据类型、小说位数) 1、首先在显示ALV的子FORM(F_DISPLAY)里定义“回调”的变量,如下: " 回调变量 DATA: i_grid_settings TYPE lvc_s_glay . i_grid_settings-edt_cll_cb = 'X' . 2、在显示ALV的函数(REUSE_ALV_GRID_DISPLAY_LVC)里添加输入参数如,下: i_grid_settings = i_grid_settings 这时只要在显示界面可编辑字段上修改了数据,回车后就会立即将内表的数据也修改了; 3、对于货币字段,要在其设置字段和列名的属性中再添加一个“指定数据类型”的属性,如下: wa_fieldcat-datatype = 'CURR' . " 指定数据类型 这样在修改数据并保存时,才能将数据保持原样,否则输入的数据会自动将小数点提前2位; 4、对于数量字段,也要添加一个“指定数据类型”的属性,才能保持数据的正确性,如下: wa_fieldcat-datatype = 'QUAN' . " 指定数据类型 wa_fieldcat-inttype = 'C' . 5、将界面数据保存到数据库表中,触发事件见子FORM中的F_SAVE_DATA,代码如下: FORM f_save_date . DATA: i_spfli LIKE TABLE OF spfli WITH HEADER LINE . DATA: l_error TYPE REF TO cx_sy_open_sql_db , l_error2 TYPE REF TO cx_sy_arithmetic_overflow , l_error_text TYPE string . " 将界面上的数据转接到和被修改的数据库表的结构一样的内表中 LOOP AT i_tab INTO wa_tab . i_spfli-carrid = 'ZZ' . i_spfli-connid = sy-tabix . i_spfli-cityfrom = wa_tab-cityfrom . i_spfli-airpfrom = wa_tab-airpfrom . i_spfli-cityto = wa_tab-cityto . i_spfli-airpto = wa_tab-airpto . i_spfli-distance = wa_tab-distance . APPEND i_spfli . CLEAR i_spfli . ENDLOOP. " 保存到数据库 TRY . DELETE spfli FROM TABLE i_spfli . INSERT spfli FROM TABLE i_spfli . CATCH cx_sy_open_sql_db INTO l_error . l_error_text = l_error->get_text( ) . sy-subrc = 1 . ENDTRY . IF sy-subrc NE 0 . ROLLBACK WORK . MESSAGE e000 WITH l_error_text . CLEAR l_error_text . ELSE . MESSAGE s000 WITH '数据保存成功!' . ENDIF. CLEAR i_spfli . REFRESH i_spfli . ENDFORM. " f_save_date ALV自带的复选框按钮: 在定义内表时,需要指明代表复选框的字段,这里如:BOX_NAME,然后在定义ALV全局属性的子FORM(F_BUILD_LAYOUT)里指明代表复选框的字段,如下: i_layout-box_fname = box_fname . 自定义复选框按钮2 .
