一、ALV相关概念
ALV――ABAP LIST VIEWER,这里我们姑且称之为ABAP表单浏览器,用它可以标准化,简单化R/3系统中的表单,它可以提供给用户一个统一的表单格式以及用户接口。
二、程序的编写
1.写一个ALV程序的基本流程:
第一步:定义将要用到的表,即TALBES定义部分,然后定义TYPE-POOLS: SLIS.
第二步:定义第一步中提到的这些数据类型或者内表的实体对象 ,内表结构
第三步:定义一些需要用到的变量
第四步: 定义自己的选择屏幕
第五步: start-of-selection部分
1用一个子函数完成自己所需要数据的抓取,也可以直接取数
2用一个子函数完成要显示列表的列名行(第一行)的相关赋值(i_fieldcat_alv)以及设置
3用一个子函数完成输出格式的设置(i_layout),比如双击一条记录是否弹出对话框啊?是用哪个功能键触发等等
4用一个子函数FORM DISPLAY_DATA来显示上面我们已经分别封装好的数据,需要调用两个常用的FUNCTION MODULE:
FUNCTION 'REUSE_ALV_GRID_DISPLAY' “用来显示表单数据
FUNCTION 'REUSE_ALV_COMMENTARY_WRITE' “用来显示表单标题
5定义某些事件
6定义排序
7定义ALV报表可编辑及更新数据库表
2.在我们写ALV程序的时候,有一个类型组是肯定要用到的:
TYPE-POOLS:SLIS。
在这个类型组中有很多ALV的自定义数据类型以及结构化数据类型(通过TYPE来定义的),我们在写ALV表单的时候需要调用的。我们常用的几个有(蓝色部分):
3. 两个重要的数据结构
(1)catalogt属性 (每列对应一个这样的结构slis_fieldcat_alv,所有的列信息存储到内表中slis_t_fieldcat_alv)
fieldname |
内表字段 |
coltext |
显示的列头 |
just |
对齐方式(R,L,C) |
seltext |
提示信息 |
emphasize |
输入列的颜色, Cxyz 如果后面不设置那么前列后填充后列 |
no_merging |
排序时不合并 |
no_zero |
消除‘0’输出 |
no_sign |
消除正负号 |
hotspot |
输入热区,小手+下划线 (填充后列) |
do_sum=‘X’ |
列合计(设置后初始化便出现合计了) |
no_sum=’X’ |
禁止列合计 |
checkbox |
输出一个checkbox 不能更改 |
col_pos |
列输出位置 |
inttype |
列的数据类型 |
col_pos |
输出列 |
tabname |
标签名称 |
currency(5) |
货币单位 |
quantity(3) |
计量单位 |
qfieldname |
参考计量单位的字段名称 |
round |
ROUND 值 |
exponent(3) |
流动表示的指数 |
key(1) |
关键字段 |
icon(1) |
作为图标输出 |
symbol(1) |
输出作为符号 |
checkbox(1) |
作为复选框输出 |
lzero(1) |
输出前导零 |
no_sign(1) |
输出抑制符号 |
no_zero(1) |
为输出隐藏零 |
edit_mask |
为输出编辑掩码 |
fix_column(1) |
固定列 |
do_sum(1) |
总计列值 "汇总,该字段在ALV的最底部汇总 |
no_out(1) |
列没有输出 |
tech(1) |
技术字段 |
outputlen |
列的字符宽度 |
decimals_out |
控制小数点的位数 |
(2)Layout 属性(slis_layout_alv 仅是个扁平的结构,存储控制ALV样式的信息)
no_colhead(1) type c, |
" no headings 没有标题 |
no_hotspot(1) type c, |
" headings not as hotspot 标题不作为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 不压制领域复制 |
edit(1) type c, |
" for grid only 仅为grid |
edit_mode(1) type c, |
" for grid only 仅为grid |
numc_sum(1) type c, |
" totals for NUMC-Fields possib. 数字型字段可集计 |
no_input(1) type c, |
" only display fields 仅显示 |
f2code like sy-ucomm, |
"设置触发弹出详细信息窗口的功能码 |
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' 缺省状态空间或‘A’ |
item_text(20) type c,
|
" Text for item button 文本为项目按钮 |
* Display options 显示属性 |
|
colwidth_optimize(1) type c, |
|
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 |
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 |
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_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 |
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 Fullscreen to List |
下面直接上代码
*&---------------------------------------------------------------------*
*& Report YPMRP010_ALV01
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT YPMRP010_ALV01.
*-----设定变量-------*
TYPE-POOLS:SLIS.
TABLES:VBAP.
*定义ALV结构
DATA:LT_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV."FIELDCAT内表
DATA:LS_FIELDCAT TYPE SLIS_FIELDCAT_ALV."FIELDCAT工作区
DATA:LS_LAYOUT TYPE SLIS_LAYOUT_ALV."ALV控制结构体:layout
DATA:LT_EVENT TYPE SLIS_T_EVENT."事件内表
DATA:LS_EVENT TYPE SLIS_ALV_EVENT."事件工作区
DATA:LT_SORT TYPE SLIS_T_SORTINFO_ALV. "用于排序的内表
DATA:LS_SORT TYPE SLIS_SORTINFO_ALV."用于排序的工作区
DATA:LS_SETTING TYPE LVC_S_GLAY."ALV 控制: 退出可编辑单元格时回调
*定义内表结构
TYPES:BEGIN OF TY_ALVSHOW,
VBELN LIKE VBAK-VBELN,
ERDAT LIKE VBAK-ERDAT,
ERNAM LIKE VBAK-ERNAM,
KUNNR LIKE VBAK-KUNNR,
POSNR LIKE VBAP-POSNR,
MATNR LIKE VBAP-MATNR,
MATKL LIKE VBAP-MATKL,
ZMENG LIKE VBAP-ZMENG,
ZIEME LIKE VBAP-ZIEME,
WERKS LIKE VBAP-WERKS,
LGORT LIKE VBAP-LGORT,
END OF TY_ALVSHOW.
*定义内表及工作区
DATA:IT_ALVSHOW TYPE STANDARD TABLE OF TY_ALVSHOW.
DATA:WA_ALVSHOW TYPE TY_ALVSHOW.
DATA:IT_ALVSHOW1 TYPE STANDARD TABLE OF TY_ALVSHOW.
DATA:WA_ALVSHOW1 TYPE TY_ALVSHOW.
DATA:COL_POS TYPE I.
SELECT-OPTIONS:S_VBELN FOR VBAP-VBELN.
*取数据
SELECT
VBAK~VBELN VBAK~ERDAT VBAK~ERNAM VBAK~KUNNR VBAP~POSNR VBAP~MATNR VBAP~MATKL
VBAP~ZMENG VBAP~ZIEME VBAP~WERKS VBAP~LGORT FROM VBAK
INNER JOIN VBAP ON VBAK~VBELN = VBAP~VBELN
* INTO CORRESPONDING FIELDS OF TABLE IT_ALVSHOW WHERE VBAK~VBELN IN S_VBELN.
INTO CORRESPONDING FIELDS OF TABLE IT_ALVSHOW UP TO 5 ROWS.
IT_ALVSHOW1 = IT_ALVSHOW.
*ALV格式控制layout
LS_LAYOUT-ZEBRA = 'X'.
LS_LAYOUT-DETAIL_POPUP = 'X'.
LS_LAYOUT-DETAIL_TITLEBAR = '详细信息'.
LS_LAYOUT-F2CODE = '&ETA'.
LS_LAYOUT-COLWIDTH_OPTIMIZE = 'X'.
* fieldcat
COL_POS = 0.
*销售凭证列
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'VBELN'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-KEY = 'X'.
LS_FIELDCAT-SELTEXT_M = '销售凭证'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*创建日期
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'ERDAT'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-REF_TABNAME = 'VBAK'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*创建者
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'ERNAM'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-SELTEXT_M = '创建人'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*售达方 自己起字段描述
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'KUNNR'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-SELTEXT_M = '客户'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*售达方1 参考数据字典表名
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'KUNNR'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-REF_TABNAME = 'VBAK'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*行号
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'POSNR'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-REF_TABNAME = 'VBAP'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*物料
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'MATNR'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-SELTEXT_M = '物料编码'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*物料组
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'MATKL'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-SELTEXT_M = '物料组'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*数量
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'ZMENG'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-SELTEXT_M = '数量'.
LS_FIELDCAT-DO_SUM = 'X'. "总计
LS_FIELDCAT-EDIT = 'X'. "总计
LS_FIELDCAT-DECIMALS_OUT = 3. "因为当编辑数量的时候,如果是小数,要指定小数位,否则输入数据之后回车会自动缩小,如果使用ref则不需要设置
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*单位
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'ZIEME'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-SELTEXT_M = '单位'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*工厂
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'WERKS'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-REF_TABNAME = 'VBAP'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*库位
COL_POS = COL_POS + 1.
LS_FIELDCAT-FIELDNAME = 'LGORT'.
LS_FIELDCAT-COL_POS = COL_POS.
LS_FIELDCAT-SELTEXT_M = '库位'.
APPEND LS_FIELDCAT TO LT_FIELDCAT.
CLEAR:LS_FIELDCAT.
*定义事件
LS_EVENT-NAME = 'USER_COMMAND'."用户响应事件
LS_EVENT-FORM = 'FORM_USER_COMMAND'."子例程
APPEND LS_EVENT TO LT_EVENT."加入到事件内表
CLEAR:LS_EVENT.
LS_EVENT-NAME = 'TOP_OF_PAGE'."显示标题
LS_EVENT-FORM = 'FORM_TOP_OF_PAGE'."子例程
APPEND LS_EVENT TO LT_EVENT.
CLEAR:LS_EVENT.
LS_EVENT-NAME = 'PF_STATUS_SET'."设置gui状态栏
LS_EVENT-FORM = 'FORM_PF_STATUS_SET'."子例程
APPEND LS_EVENT TO LT_EVENT.
CLEAR:LS_EVENT.
*排序
LS_SORT-FIELDNAME = 'ERDAT'.
LS_SORT-DOWN = 'X'.
APPEND LS_SORT TO LT_SORT.
LS_SORT-FIELDNAME = 'KUNNR'.
LS_SORT-UP = 'X'.
APPEND LS_SORT TO LT_SORT.
CLEAR:LS_SORT.
*ALV 控制: 退出可编辑单元格时回调
LS_SETTING-EDT_CLL_CB = 'X'.
*显示
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 =
* I_BACKGROUND_ID = ' '
* I_GRID_TITLE =
I_GRID_SETTINGS = LS_SETTING "退出可编辑单元格时回调保存修改的值,修改了值必须要按回车健激活
IS_LAYOUT = LS_LAYOUT
IT_FIELDCAT = LT_FIELDCAT
* IT_EXCLUDING =
* IT_SPECIAL_GROUPS =
IT_SORT = LT_SORT
* IT_FILTER =
* IS_SEL_HIDE =
* I_DEFAULT = 'X'
* I_SAVE = ' '
* IS_VARIANT =
IT_EVENTS = LT_EVENT
* 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 = IT_ALVSHOW
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2.
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.
"FORM define
FORM FORM_USER_COMMAND USING R_UCOMM LIKE SY-UCOMM
RS_SELFIELD TYPE SLIS_SELFIELD.
* DATA:IT_VBAP TYPE TABLE OF VBAP."更新源内表,要和数据库表结构一致 7.5以前可以定义内表
* DATA:WA_VBAP TYPE VBAP.
* CASE .
* WHEN .
* WHEN .
* WHEN OTHERS.
* ENDCASE. 也可以用case
IF R_UCOMM = '&ADD'.
MESSAGE '您触发了按钮TEST' TYPE 'I'.
ENDIF.
IF R_UCOMM = 'ZSAVE'.
* SELECT * FROM VBAP INTO TABLE @DATA(LT_VBAP) FOR ALL ENTRIES IN @IT_ALVSHOW"7.5以后可以直接@data内表名
* WHERE VBELN = @IT_ALVSHOW-VBELN AND POSNR = @IT_ALVSHOW-POSNR.
* LOOP AT LT_VBAP INTO DATA(WA_VBAP).
* READ TABLE IT_ALVSHOW INTO WA_ALVSHOW WITH KEY VBELN = WA_VBAP-VBELN POSNR = WA_VBAP-POSNR.
* IF SY-SUBRC = 0.
* WA_VBAP-ZMENG = WA_ALVSHOW-ZMENG.
* MODIFY LT_VBAP FROM WA_VBAP.
* CLEAR:WA_VBAP,WA_ALVSHOW.
* UPDATE VBAP FROM TABLE LT_VBAP.
* ENDIF.
* ENDLOOP.
DATA:TABLE_DEL TYPE TABLE OF TY_ALVSHOW.
DATA:TABLE_ADD TYPE TABLE OF TY_ALVSHOW.
DATA:TABLE_MOD TYPE TABLE OF TY_ALVSHOW.
DATA:WA_TABLE_MOD TYPE TY_ALVSHOW.
DATA:NO_CHANGES(1) TYPE C.
CALL FUNCTION 'CTVB_COMPARE_TABLES' "用于比较更改前后内表的变化,比上面的全部循环更新更有效率
EXPORTING
TABLE_OLD = IT_ALVSHOW1
TABLE_NEW = IT_ALVSHOW
KEY_LENGTH = '2'
* IF_SORTED =
IMPORTING
TABLE_DEL = TABLE_DEL
TABLE_ADD = TABLE_ADD
TABLE_MOD = TABLE_MOD
NO_CHANGES = NO_CHANGES.
SELECT * FROM VBAP INTO TABLE @DATA(LT_VBAP) FOR ALL ENTRIES IN @TABLE_MOD"7.5以后可以直接@data内表名
WHERE VBELN = @TABLE_MOD-VBELN AND POSNR = @TABLE_MOD-POSNR.
LOOP AT LT_VBAP INTO DATA(WA_VBAP).
READ TABLE TABLE_MOD INTO WA_TABLE_MOD WITH KEY VBELN = WA_VBAP-VBELN POSNR = WA_VBAP-POSNR.
IF SY-SUBRC = 0.
WA_VBAP-ZMENG = WA_TABLE_MOD-ZMENG.
MODIFY LT_VBAP FROM WA_VBAP.
CLEAR:WA_VBAP,WA_TABLE_MOD.
UPDATE VBAP FROM TABLE LT_VBAP.
ENDIF.
ENDLOOP.
IF SY-SUBRC = 0.
COMMIT WORK. "用于提交数据
MESSAGE '更新成功' TYPE 'I'.
ELSE.
ROLLBACK WORK.
MESSAGE '更新失败' TYPE 'I'.
ENDIF.
ENDIF.
ENDFORM.
FORM FORM_TOP_OF_PAGE.
DATA:LT_COMMENTARY TYPE SLIS_T_LISTHEADER,
WA_COMMENTARY TYPE SLIS_LISTHEADER.
WA_COMMENTARY-TYP = 'H'.
WA_COMMENTARY-INFO = '销售凭证'.
APPEND WA_COMMENTARY TO LT_COMMENTARY.
CLEAR:WA_COMMENTARY.
WA_COMMENTARY-TYP = 'S'.
WA_COMMENTARY-INFO = '销售凭证'.
APPEND WA_COMMENTARY TO LT_COMMENTARY.
CLEAR:WA_COMMENTARY.
WA_COMMENTARY-TYP = 'A'.
WA_COMMENTARY-INFO = '销售凭证'.
APPEND WA_COMMENTARY TO LT_COMMENTARY.
CLEAR:WA_COMMENTARY.
CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE' "用于ALV标题的显示
EXPORTING
IT_LIST_COMMENTARY = LT_COMMENTARY
I_LOGO = 'ZTEST1'.
* I_END_OF_LIST_GRID =
* I_ALV_FORM =
ENDFORM.
FORM FORM_PF_STATUS_SET USING RT_EXTAB TYPE SLIS_T_EXTAB.
SET PF-STATUS'STANDARD'.
ENDFORM.