ALV详解:Function ALV(二)

时间:2023-03-08 23:44:53
ALV详解:Function ALV(二)
ALV详解:Function ALV(二)
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将追究法律责任!原文链接:http://www.cnblogs.com/jiangzhengjun/p/4291344.html

Function ALV

单元格数据修改后立即同步(即立即触发DATA_CHANGED事件)输出内表

如果修改了网格中数据,如果没有设置在单元格内容被修改后失去焦点(或回车)时立即同步到输出内表中(即立触发DATA_CHANGED事件),则输出内表中的数据要等到保存、刷新、切换布局等按钮执行后,才会触发DATA_CHANGED事件,将修改过的数据更新到输出内表中,如果要求在数据修改失去焦点时立即同步到输出内表,则有以下两种方法:

方法一:通过REUSE_ALV_GRID_DISPLAY 函数的i_grid_settings-edt_cll_cb进行设置:

.
  WRITE: gt_data-key1.

FORM inital .
  gt_data-key1 = 'a'.
  gt_data-key2 = 'aa'.
  APPEND gt_data.
ENDFORM.

方法二:在user_command 回调Form处理:

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program       = sy-cprog
      i_callback_user_command  = 'USER_COMMAND'
      it_fieldcat              = fieldcat[]
    TABLES
      t_outtab                 = gt_data.

FORM user_command USING ucomm  LIKE sy-ucommselfield  selfield TYPE slis_selfield.
DATAl_ref1 TYPE REF TO cl_gui_alv_grid.
  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = l_ref1.
  CALL METHOD l_ref1->check_changed_data. "调用此方法后会触发DATA_CHANGED事件。当此方法执行完后,被修改的数据就会更新到输出内表中了
 "好像没有上面几行代码,只需下面一行也可以自动更新,上面代码究竟有什么作用?
  selfield-refresh = 'X'.
  CASE ucomm.
    WHEN 'UPDATE'.
      PERFORM frm_update.
  ENDCASE.
ENDFORM.

输出内表数据更新前触发DATA_CHANGE事件进行数据有效性验证

在DATA_CHANGE事件触发时,可进一步检查数据输入的正确性

),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> = ls_cells-value.
    "实际上不需要此句来修改输出内表中的数据,因为只要在该Form中不
    "弹出 E MSG,则该Form执行完后会也会自动更新输出内表
    "MODIFY gt_data INDEX ls_cells-row_id.
  ENDLOOP.

ENDFORM.
FORM inital .
  gt_data-key1 = 'a'.
  gt_data-key2 = 'aa'.
  APPEND gt_data.
ENDFORM.

REUSE_ALV_GRID_DISPLAY[_LVC]函数中获取生成的OO ALV对象

有时REUSE_ALV_GRID_DISPLAY、REUSE_ALV_GRID_DISPLAY_LVC函数并不能满足我们的需要,如通过REUSE_ALV_GRID_DISPLAY_LVC函数设置单元格显示为PushButton时,无法针对Button的单元事件进行处理,所以只能借助于OO的ALV。只需在代码中加入如下代码,即可获取到当前所产生的OO ALV对象,当拿到此对象后,就可以通过cl_gui_alv_grid来完成函数所无法完成的功能:

DATA l_ref1 TYPE REF TO cl_gui_alv_grid.
  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = l_ref1.

除此方法后,还可以在程序中动态获取此对象,可以参考这里

货币类、数量(P小数)类型字段修改时小数点问题

对于货币与P类型小数(如数量)类型字段,需要对gt_fieldcat-datatype属性进行设置,才能将输入的数字保持原样大小,否则输入的数据会自动将小数点提前2位;对于数量类型,好像还需要对gt_fieldcat-INTTYPE属性进行设置才好使,并且只能设置为C类型。datatype与INTTYPE实质上就是一种编辑类型与数据库字段类型的映射,即Hibernate中的ORM(对象关系映射)

datatypeABAP字典中数据库类型,即SE11创建表结构时所参照的数据库字段类型(ABAP词典类型),取值如下:

ACCP   Posting period YYYYMM
CHAR   Character String
CLNT   Client
CUKY   Currency key, referenced by CURR fields
CURR  Currency field, stored as DEC
D16D   Decimal Floating Point, 16 Digits, DEC on Database
D16R   Decimal Floating Point, 16 Digits,  RAW on Database
D16S   Decimal Floating Point. 16 Digits, with Scale Field
D34R   Decimal Floating Point, 34 Digits, RAW on Database
D34S   Decimal Floating Point, 34 Digits, with Scale Field
DATS   Date field (YYYYMMDD) stored as char(8)
DEC Counter or amount field with comma and sign
FLTP   Floating point number, accurate to 8 bytes
INT1   1-byte integer, integer number <= 255
INT2   2-byte integer, only for length field before LCHR or LRAW
INT4   4-byte integer, integer number with sign
LANG   Language key
LCHR   Long character string, requires preceding INT2 field
LRAW   Long byte string, requires preceding INT2 field
NUMC   Character string with only digits
PREC   Obsolete data type, do not use
QUAN  Quantity field, points to a unit field with format UNIT
RAW Uninterpreted sequence of bytes
RSTR   Byte String of Variable Length
SSTR   Short Character String of Variable Length
STRG   Character String of Variable Length
TIMS   Time field (hhmmss), stored as char(6)
UNIT   Unit key for QUAN fields
VARC   Long character string, no longer supported from Rel. 3.0

INTTYPE:ABAP程序内部所使用的一种数据类型,即ABAP数据类型,取值如下:

C   Character String
N   Character String with Digits Only
D   Date (Date: YYYYMMDD)
T   Time (Time: HHMMSS)
X   Byte Seq. (heXadecimal), in DDIC metadata also for INT1/2/4
I   Integer number (4-byte integer with sign)
b   1-byte integer, integer number <= 254
s   2-byte integer, only for length field before LCHR or LRAW
P   Packed number
F   Floating point number to accuracy of 8 bytes
g   Character string with variable length (ABAP type STRING)
y   Byte sequence with variable length (ABAP type XSTRING)
u   Structured type, flat
v   Structured type, deep
h   Table type
V   Character string (old Dictionary type VARC)
r   Reference to class/interface
l   Reference to data object
a   Decimal Floating Point Number, 16 Digits
e   Decimal Floating Point Number, 34 Digits
j   Static Boxed Components
k   Generic Boxed Components

ALV详解:Function ALV(二)

.
  APPEND gt_data.
ENDFORM.

排序、汇总

GRIDALV排序、分类汇总

排序之前,如果同一列有相同的数据,则排好序以后,在该列会自动将相同的数据合并为一行显示,不再出现多行重复的情况(但是若该ALV中有字段设置了“可编辑”,合并这一现象会失效)

只要某字段参设置了gt_sort-down/up,则在展示时,排序以后垂直的网格中相邻相同的单元格就会合并起来(即分类合并,如果要避免合并,请在布局中设置"no_merging"为"X"),而不是看是否设置了gt_sort-subtot属性(该设置只会决定是否进行大汇总与分类小计):

gt_sort-spos = '2'."排序的顺序,如果根据多个字段来排时,决定哪个先排
  gt_sort-fieldname = 'KEY2'.
  gt_sort-down = 'X'."降序
* gt_sort-subtot    = 'X'.
  APPEND gt_sort.

ALV详解:Function ALV(二)

虽然INT1、INT2设置了gt_fieldcat-do_sum属性,但没有设置gt_sort-subtot,所以没有进行分类小计,只是对整列进行了合计(如需分类小计,则需要设置gt_sort-subtot):

"需要进行统计的字段:INT1、INT2
    if &1 = 'INT1' or &1 = 'INT2'.
      gt_fieldcat-do_sum = 'X'.
    endif.
gt_sort-spos = '2'."排序的顺序,如果根据多个字段来排时,决定哪个先排
  gt_sort-fieldname = 'KEY2'.
  gt_sort-down = 'X'."降序
  APPEND gt_sort.

ALV详解:Function ALV(二)

设置gt_sort-subtot后,才会对该列进行分类小计:

"需要进行统计的字段:INT1、INT2
    if &1 = 'INT1' or &1 = 'INT2'.
      gt_fieldcat-do_sum = 'X'.
    endif.
 gt_sort-spos = '2'."排序的顺序,如果根据多个字段来排时,决定哪个先排
  gt_sort-fieldname = 'KEY2'.
  gt_sort-down = 'X'."降序
*  "是否需要以此字段进行分类合并、并进行小计(注:与本列是否参与排序无关系,只要设置此属性
*  "就进行分类合并且小计,但如果设置了按其他列排序,则会对此列分类合并有影响——即
*  "相同类型的单格不一定会合并成一个单元格,可能会合并出多个),另外,小计的前提条件是要对gt_fieldcat-do_sum进行了设置
  gt_sort-subtot    = 'X'.
  APPEND gt_sort.

ALV详解:Function ALV(二)

根据KEY1、KEY2多列进行排序且小计:

ALV详解:Function ALV(二)

下面是完整代码:

.
  APPEND gt_data.
ENDFORM.

小分类分隔方式(GROUP = */UL),仅适用于LIST输出的ALV

gt_sort-group = '*/UL'只在REUSE_ALV_LIST_DISPLAY列表方式输出时起作用,对  "REUSE_ALV_GRID_DISPLAY网格输出方式不起作用

.
  APPEND gt_data.
ENDFORM.

无分隔时(不设置gt_sort-group)

ALV详解:Function ALV(二)

线分隔(gt_sort-group = 'UL')

ALV详解:Function ALV(二)

分页方式分隔(gt_sort-group = '*')

ALV详解:Function ALV(二)

表头信息说明

可以通过两种回调方式来实现,第一种:直接通过REUSE_ALV_GRID_DISPLAY函数的i_callback_html_top_of_page来回调Form;第二种:通过REUSE_ALV_GRID_DISPLAY函数的it_events参数接口,向事件内表中Append事件top_of_page与对应的Form

i_callback_html_top_of_page参数回调接口

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      it_fieldcat                 = fieldcat[]
      i_callback_program         
= sy-repid
     i_callback_html_top_of_page 
= 'HTML_TOP_OF_PAGE'
   
TABLES
      t_outtab                   
= t_stock[].

FORM html_top_of_pageUSING r_ddoc TYPE REF TO cl_dd_document.
  DATA: text TYPE sdydo_text_element.
  CALL METHOD r_ddoc->initialize_document.
  CALL METHOD r_ddoc->add_text"控制输出字体为粗体
    EXPORTING
     text = '行状态图标含义'
     sap_emphasis = 'STRONG'.

DEFINE write_inf.
    call method r_ddoc->new_line."换行
    call method r_ddoc->add_icon"输出图标
      exporting
        sap_icon = &1.
    call method r_ddoc->add_text"输出文本
      exporting
        text = &2.
  END-OF-DEFINITION.

write_inf 'ICON_GREEN_LIGHT' ':商品可用库存'."表头输出的图标及类型
  write_inf 'ICON_RED_LIGHT' ':商品非可用库存'.
ENDFORM.

ALV详解:Function ALV(二)

top_of_page事件

位,有一定的局限性,但可采用另一种而向对象方式来实现解决

ALV详解:Function ALV(二)

(字体加粗,长度无限制):'(正常字体,长度无限制)' (正常字体,长度无限制)' (字体加粗,长度无限制):'、60),所以超出此宽度的长度无法输出,此时
个字符)'.
个字符):'.
个字符)'.
个字符)'.
.
  APPEND gt_data.
ENDFORM.

ALV-F4-Layout、布局变式切换捕获(动态访问函数中定义的全局变量)

REUSE_ALV_GRID_DISPLAY函数的i_save参数值决定了ALV的布局相关的变式,是否可修改及是否只用于特定用户:
' ' = Display variants cannot be saved显示变式,但不能修改,此为默认值
'X' = Standard save mode 标准的保存模式,此模式下变式可存储为标准的变式,但不能存储为用户模式
'U' = User-specific save mode 用户保存模式,哪个创建,只能哪个来用
'A' = Standard and user-specific save mode 标准与用户模式,此模式下可以选择存储为标准还是用户变式

ALV详解:Function ALV(二)这三个按钮分配是布局修改、布局选择、布局保存,如果不输入或输入空时,没有保存布局ALV详解:Function ALV(二)按钮,如 i_save = 'X'情况下创建创建布局变式:

ALV详解:Function ALV(二)

i_save = 'U'情况下创建创建布局变式:

ALV详解:Function ALV(二)

在 i_save = 'A'情况下创建创建布局变式:

ALV详解:Function ALV(二)

当创建完上面三个模式的布局变式时,选择布局时,看到的情况如下:

ALV详解:Function ALV(二)

另外,在创建布局变式时,可以选择是否将某个布局变式设设置为默认的布局,这样在REUSE_ALV_GRID_DISPLAY函数调用时,没有传递is_variant 时,会默认采用此处设置的默认布局,另外默认布局还可以被REUSE_ALV_VARIANT_DEFAULT_GET函数读取出来:

ALV详解:Function ALV(二)

该程序实现了屏幕上选择Layout、获取默认的Layout、检查输入的Layout变式是否存在,获取当前使用的Layout中的显示字段与显示的顺序

ALV详解:Function ALV(二)

.
  lt_stock-color = 'C300'.
  APPEND lt_stock .
ENDFORM.

ALV详解:Function ALV(二)

ALV详解:Function ALV(二)

红绿灯(layout-lights_fieldname)

ALV详解:Function ALV(二)

),
  sel, "选择列
END OF gt_data.

START-OF-SELECTION.
  PERFORM inital.
  DEFINE fill_fdcat.
    clear gt_fieldcat.
    gt_fieldcat-fieldname = &1.
    gt_fieldcat-seltext_l = &2.
    "请注意:这里一定要设置一下ddictxt,否则light列标题将显示为Exception
    gt_fieldcat-ddictxt= &3.
    append gt_fieldcat.
  END-OF-DEFINITION.

fill_fdcat 'LIGHT' '红绿灯'  'L'.
  fill_fdcat 'VAL' '值'  'L'.

gs_layout-lights_fieldname  = 'LIGHT'."指定灯列名

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

FORMinital .
  gt_data-light = ' '."取值范围为:空、1~3
  gt_data-val = '空'.
  APPEND gt_data .

gt_data-light = '1'.
  gt_data-val = '1'.
  APPEND gt_data .

gt_data-light = '2'.
  gt_data-val = '2'.
  APPEND gt_data .

gt_data-light = '3'.
  gt_data-val = '3'.
  APPEND gt_data .
ENDFORM.

F4帮助

ALV详解:Function ALV(二)
,
  werks LIKE mard-werks,"工厂
  matnr LIKE mara-matnr,"物料
  END OF t_stock.

INITIALIZATION.
  PERFORM inital.

START-OF-SELECTION.

DEFINE fill_fdcat.
    clear fieldcat.
    fieldcat-fieldname = &1.
    fieldcat-seltext_l = &2.
    fieldcat-key = &3.
    "如果不设为可编辑,则F4帮助只能看,不能选
    fieldcat-edit = 'X'.
    if &1  = 'WERKS'.
      fieldcat-ref_tabname   = 'MARD'. "F4帮助,参照的表
      fieldcat-ref_fieldname = 'WERKS'."F4帮助,参照的表中哪个字段
    endif.
    append fieldcat.
  END-OF-DEFINITION.

fill_fdcat 'WERKS' 'WERKS' ''.
  fill_fdcat 'MATNR' 'MATNR' ''.

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      it_fieldcat = fieldcat[]
    TABLES
      t_outtab    = t_stock.

FORM inital .
  t_stock-werks = '1001'.
  t_stock-matnr = '1001M1'.
  APPEND t_stock .
ENDFORM.

行多选按钮、复选框

ALV详解:Function ALV(二)
注:按住CTRL键可以选择多行

,
  sel,"用来做选择按钮列ALV详解:Function ALV(二)
  checkbox,"用作复选框列ALV详解:Function ALV(二)
  werks LIKE mard-werks,
"工厂
  matnr LIKE mara-matnr,"物料
  END OF gt_stock.

INITIALIZATION.
  PERFORM inital.

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

fill_fdcat 'WERKS' '工厂' 'X'.
  fill_fdcat 'MATNR' '物料' 'X'.
  "==========复选框设置
  CLEAR gt_fieldcat.
  gt_fieldcat-seltext_l = '复选框'.
  gt_fieldcat-fieldname = 'SEL'.
"当用户点击复选框后,如需将数据更新到输出内表中,则需对REUSE_ALV_GRID_DISPLAY函数参数i_grid_settings-edt_cll_cb进行设置
  gt_fieldcat-checkbox = 'X'.
  APPEND gt_fieldcat.

gs_layout-box_fieldname = 'CHECKBOX'."行多选择按钮设置

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      it_fieldcat = gt_fieldcat[]
      is_layout   = gs_layout
    TABLES
      t_outtab    = gt_stock.

FORM inital .
  gt_stock-sel = 'X'.
  gt_stock-checkbox = 'X'.
  gt_stock-werks = '1001'.
  gt_stock-matnr = '1001M1'.
  APPEND gt_stock .

CLEAR:gt_stock.
  gt_stock-sel = 'X'.
  gt_stock-werks = '1001'.
  gt_stock-matnr = '1001M2'.
  APPEND gt_stock .
ENDFORM.

ALV报表标题

ALV详解:Function ALV(二)

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      it_fieldcat = gt_fieldcat[]
      i_grid_title = 'ALV报表标题'
    TABLES
      t_outtab    = gt_data.

热点

ALV详解:Function ALV(二)

) WITH '热点触发事务码:'  r_ucomm.
ENDFORM.

FORM inital .
  gt_data-key1 = 'a'.
  gt_data-key2 = 'aa'.
  APPEND gt_data.
ENDFORM.