SAP中SALV的输出

目录

1.常见SALV输出中的各种情况

2. 在 CL_SALV_TABLE 输出中增加 GUI 状态

2.2. 创建 GUI 状态的方法

2.3. 注意事项

3. 高级定制选项

4. 解决 lcl_handler 未知类型错误

4.1. 完整解决方案

4.2. 修改ALV显示代码

4.3. 完整示例程序

4.4. 关键点说明

5. 在 CL_SALV_TABLE 中修改输出列名称

5.1. 方法一:使用列对象的 set_short_text/set_long_text/set_medium_text

5.2. 方法二:批量设置列标题

5.3. 方法三:使用字典结构的文本标识

5.4. 完整示例

5.5. 注意事项

6. 在 CL_SALV_TABLE 中控制输出字段(隐藏不需要的字段)

6.1. 方法一:使用 set_visible 隐藏特定列

6.2. 方法二:使用 set_technical 隐藏技术字段

6.3. 方法三:预先处理数据(推荐)

6.4. 方法四:使用字段目录控制显示

6.5. 完整示例

6.6. 方法比较


1.常见SALV输出中的各种情况

  DATA: lr_columns TYPE REF TO cl_salv_columns_table,
      lr_column  TYPE REF TO cl_salv_column_table.

  IF GT_ZFI027A IS INITIAL.
    MESSAGE '没有满足条件的数据' TYPE 'S' DISPLAY LIKE 'E'.
    RETURN.
  ENDIF.

  TRY.
      CL_SALV_TABLE=>FACTORY(
        IMPORTING
          R_SALV_TABLE = DATA(LR_SALV)
        CHANGING
          T_TABLE      = GT_ZFI027A
      ).
      " 设置 GUI 状态
      SET PF-STATUS 'STANDARD' OF PROGRAM SY-REPID. " 使用自定义状态
      SET TITLEBAR 'TITLE1'.                       " 设置标题栏

      " 添加自定义功能
      DATA(LR_FUNCTIONS) = LR_SALV->GET_FUNCTIONS( ).
      LR_FUNCTIONS->SET_ALL( ABAP_TRUE ).          " 显示所有标准功能

      " 注册事件处理(可选)
*      DATA(lr_events) = LR_SALV->get_event( ).
*      SET HANDLER lcl_handler=>on_user_command FOR lr_events. "这里需要定义事件处理类lcl_handler

      " 可以进一步定制 ALV 显示
      DATA(LR_DISPLAY) = LR_SALV->GET_DISPLAY_SETTINGS( ).
      LR_DISPLAY->SET_STRIPED_PATTERN( ABAP_TRUE ).  " 斑马线样式

*       lr_display->set_list_header( '我的自定义 ALV 报表' ).

      " 列优化
      LR_SALV->GET_COLUMNS( )->SET_OPTIMIZE( ABAP_TRUE ).

    " 修改特定列标题  下列情况适用于只有单独几个字段需要修改字段名称时
*TRY.
*    lr_column ?= lr_columns->get_column( 'MATNR' ).  " 物料编号字段
*    lr_column->set_short_text( '物料编号' ).        " 短文本
*    lr_column->set_medium_text( '物料编号' ).       " 中等文本
*    lr_column->set_long_text( '物料主数据编号' ).    " 长文本
*  CATCH cx_salv_not_found.
*    " 处理列不存在的情况
*ENDTRY.


" 隐藏不需要的列
" 获取列对象
lr_columns = LR_SALV->get_columns( ).

TRY.
    lr_column ?= lr_columns->get_column( 'TABIX' ). " 要隐藏的字段名
    lr_column->set_visible( abap_false ).                   " 设置为不可见
  CATCH cx_salv_not_found.
ENDTRY.

TRY.
    lr_column ?= lr_columns->get_column( 'MANDT' ). " 要隐藏的字段名
    lr_column->set_visible( abap_false ).                   " 设置为不可见
  CATCH cx_salv_not_found.
ENDTRY.

* 隐藏不需要的列 方法2
* 获取列对象
*lr_columns = gr_table->get_columns( ).
*
* 将字段标记为技术字段(会自动隐藏)
*TRY.
*    lr_column ?= lr_columns->get_column( 'TECH_FIELD' ).
*    lr_column->set_technical( abap_true ).  " 设置为技术字段
*  CATCH cx_salv_not_found.
*ENDTRY.

"而如果需要每个都改的话,则可以用下列方式
*" 获取所有列引用
*lt_cols = lr_columns->get( ).
*
*" 循环设置列标题
*LOOP AT lt_cols INTO ls_col.
*  CASE ls_col-columnname.
*    WHEN 'MATNR'.
*      ls_col-r_column->set_short_text( '物料编号' ).
*    WHEN 'MAKTX'.
*      ls_col-r_column->set_short_text( '物料描述' ).
*    WHEN 'WERKS'.
*      ls_col-r_column->set_short_text( '工厂' ).
*    WHEN 'LGORT'.
*      ls_col-r_column->set_short_text( '库存地点' ).
*    " 添加更多字段...
*  ENDCASE.
*ENDLOOP.


      LR_SALV->DISPLAY( ).
    CATCH CX_ROOT INTO DATA(LX_ERROR).
      MESSAGE 'Error displaying ALV: ' && LX_ERROR->GET_TEXT( ) TYPE 'E'.
  ENDTRY.

2. 在 CL_SALV_TABLE 输出中增加 GUI 状态

在使用 CL_SALV_TABLE=>FACTORY 显示 ALV 表格时,可以通过以下方法添加自定义 GUI 状态(菜单栏和工具栏):

2.1. 完整实现步骤

REPORT z_alv_with_gui_status.

* 定义数据
DATA: gt_data TYPE TABLE OF spfli.  " 示例数据表
DATA: gr_table TYPE REF TO cl_salv_table.

* 获取数据
SELECT * FROM spfli INTO TABLE gt_data UP TO 20 ROWS.

* 创建 ALV 显示
START-OF-SELECTION.
  TRY.
      " 创建 ALV 实例
      cl_salv_table=>factory(
        IMPORTING
          r_salv_table = gr_table
        CHANGING
          t_table      = gt_data
      ).

      " 设置 GUI 状态
      SET PF-STATUS 'MYSTATUS' OF PROGRAM sy-repid. " 使用自定义状态
      SET TITLEBAR 'TITLE1'.                       " 设置标题栏

      " 添加自定义功能
      DATA(lr_functions) = gr_table->get_functions( ).
      lr_functions->set_all( abap_true ).          " 显示所有标准功能

      " 注册事件处理(可选)
      DATA(lr_events) = gr_table->get_event( ).
      SET HANDLER lcl_handler=>on_user_command FOR lr_events.

      " 显示 ALV
      gr_table->display( ).

    CATCH cx_salv_msg INTO DATA(lx_error).
      MESSAGE lx_error->get_text( ) TYPE 'E'.
  ENDTRY.

2.2. 创建 GUI 状态的方法

  1. 在 ABAP 开发工具中创建状态
    • 进入程序属性(右键程序 → 属性)
    • 转到 "GUI 状态" 选项卡
    • 创建新状态(如 'MYSTATUS')
    • 添加菜单项和工具栏按钮
    • 定义状态代码(通常在程序顶部):

  • *&---------------------------------------------------------------------*
    *&      Module  STATUS_0100  OUTPUT
    *&---------------------------------------------------------------------*
    MODULE status_0100 OUTPUT.
      SET PF-STATUS 'MYSTATUS'.
      SET TITLEBAR 'TITLE1'.
    ENDMODULE.
  • 事件处理类示例(用于处理用户命令):
CLASS lcl_handler DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      on_user_command FOR EVENT added_function OF cl_salv_events
        IMPORTING e_salv_function.
ENDCLASS.

CLASS lcl_handler IMPLEMENTATION.
  METHOD on_user_command.
    CASE e_salv_function.
      WHEN 'MYFUNCTION1'.
        MESSAGE '自定义功能1被触发' TYPE 'I'.
      WHEN 'MYFUNCTION2'.
        MESSAGE '自定义功能2被触发' TYPE 'I'.
      WHEN OTHERS.
        " 处理其他功能
    ENDCASE.
  ENDMETHOD.
ENDCLASS.

2.3. 注意事项

  1. 状态名称:确保 SET PF-STATUS 中使用的状态名与 GUI 状态设计中创建的名称一致
  2. 程序范围:GUI 状态必须与 ALV 程序在同一个程序中定义
  3. 功能代码:自定义按钮的功能代码必须唯一,不能与标准 ALV 功能代码冲突
  4. 权限检查:对于敏感操作,应在事件处理中添加权限检查

3. 高级定制选项

" 可以进一步定制 ALV 显示
DATA(lr_display) = gr_table->get_display_settings( ).
lr_display->set_striped_pattern( abap_true ).  " 斑马线样式
lr_display->set_list_header( '我的自定义 ALV 报表' ).

" 列优化
gr_table->get_columns( )->set_optimize( abap_true ).

4. 解决 lcl_handler 未知类型错误

当在使用 CL_SALV_TABLE 并尝试注册事件处理程序时遇到 "类型 lcl_handler 未知" 的错误,这是因为尚未定义事件处理类 lcl_handler

4.1. 完整解决方案

首先定义事件处理类

在程序顶部(START-OF-SELECTION 之前)添加以下类定义:

*---------------------------------------------------------------------*
*       CLASS lcl_event_handler DEFINITION
*---------------------------------------------------------------------*
CLASS lcl_handler DEFINITION.
  PUBLIC SECTION.
    METHODS:
      on_user_command FOR EVENT added_function OF cl_salv_events
        IMPORTING e_salv_function.
ENDCLASS.

*---------------------------------------------------------------------*
*       CLASS lcl_event_handler IMPLEMENTATION
*---------------------------------------------------------------------*
CLASS lcl_handler IMPLEMENTATION.
  METHOD on_user_command.
    CASE e_salv_function.
      WHEN 'MYFUNCTION'.  " 替换为您的功能代码
        MESSAGE '自定义功能被触发' TYPE 'I'.
      WHEN OTHERS.
        " 处理其他功能代码
    ENDCASE.
  ENDMETHOD.
ENDCLASS.

4.2. 修改ALV显示代码

START-OF-SELECTION.
  DATA: lo_handler TYPE REF TO lcl_handler.  " 声明处理程序对象
  
  TRY.
      " 创建ALV实例
      cl_salv_table=>factory(
        IMPORTING
          r_salv_table = gr_table
        CHANGING
          t_table      = gt_data
      ).

      " 创建事件处理程序实例
      CREATE OBJECT lo_handler.
      
      " 获取事件对象并注册处理程序
      DATA(lr_events) = gr_table->get_event( ).
      SET HANDLER lo_handler->on_user_command FOR lr_events.
      
      " 显示ALV
      gr_table->display( ).

    CATCH cx_salv_msg INTO DATA(lx_error).
      MESSAGE lx_error->get_text( ) TYPE 'E'.
  ENDTRY.

4.3. 完整示例程序

REPORT z_alv_with_event_handler.

* 数据定义
DATA: gt_data TYPE TABLE OF spfli,
      gr_table TYPE REF TO cl_salv_table.

* 事件处理类定义
CLASS lcl_handler DEFINITION.
  PUBLIC SECTION.
    METHODS:
      on_user_command FOR EVENT added_function OF cl_salv_events
        IMPORTING e_salv_function.
ENDCLASS.

CLASS lcl_handler IMPLEMENTATION.
  METHOD on_user_command.
    CASE e_salv_function.
      WHEN 'MYFUNCTION'.
        MESSAGE '您点击了自定义功能按钮!' TYPE 'I'.
      WHEN OTHERS.
        " 可以添加对其他功能代码的处理
    ENDCASE.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  " 获取数据
  SELECT * FROM spfli INTO TABLE gt_data UP TO 20 ROWS.
  
  " 创建ALV显示
  DATA: lo_handler TYPE REF TO lcl_handler.
  
  TRY.
      cl_salv_table=>factory(
        IMPORTING
          r_salv_table = gr_table
        CHANGING
          t_table      = gt_data
      ).
      
      " 创建处理程序实例
      CREATE OBJECT lo_handler.
      
      " 注册事件
      DATA(lr_events) = gr_table->get_event( ).
      SET HANDLER lo_handler->on_user_command FOR lr_events.
      
      " 添加自定义功能到工具栏
      DATA(lr_functions) = gr_table->get_functions( ).
      lr_functions->add_function(
        name     = 'MYFUNCTION'
        icon     = '@5D@'  " 使用SAP图标代码
        text     = '自定义功能'
        tooltip  = '这是我的自定义功能'
        position = if_salv_c_function_position=>right_of_salv_functions
      ).
      
      " 显示ALV
      gr_table->display( ).
      
    CATCH cx_salv_msg INTO DATA(lx_error).
      MESSAGE lx_error->get_text( ) TYPE 'E'.
  ENDTRY.

4.4. 关键点说明

  1. 类定义位置:必须在程序顶部定义 lcl_handler 类,然后才能在后面的代码中使用
  2. 处理程序实例化:必须使用 CREATE OBJECT 创建处理程序实例后才能注册
  3. 功能代码匹配:确保 CASE 语句中的功能代码与您添加到工具栏的代码一致
  4. 图标代码@5D@ 是SAP内部图标代码,可以在SE38中执行程序 SHOWICON 查看所有可用图标

这样修改后,您的程序就能正确识别 lcl_handler 类并处理ALV表格的事件了。

5. 在 CL_SALV_TABLE 中修改输出列名称

当使用 CL_SALV_TABLE=>FACTORY 输出数据时,可以通过以下方法修改显示的列名称(列标题),使其不显示底表字段名:

5.1. 方法一:使用列对象的 set_short_text/set_long_text/set_medium_text

DATA: lr_columns TYPE REF TO cl_salv_columns_table,
      lr_column  TYPE REF TO cl_salv_column_table.

" 获取列对象
lr_columns = gr_table->get_columns( ).

" 设置所有列优化显示
lr_columns->set_optimize( abap_true ).

" 修改特定列标题
TRY.
    lr_column ?= lr_columns->get_column( 'MATNR' ).  " 物料编号字段
    lr_column->set_short_text( '物料编号' ).        " 短文本
    lr_column->set_medium_text( '物料编号' ).       " 中等文本
    lr_column->set_long_text( '物料主数据编号' ).    " 长文本
  CATCH cx_salv_not_found.
    " 处理列不存在的情况
ENDTRY.

" 修改另一列
TRY.
    lr_column ?= lr_columns->get_column( 'WERKS' ).  " 工厂字段
    lr_column->set_short_text( '工厂' ).
    lr_column->set_long_text( '生产工厂' ).
  CATCH cx_salv_not_found.
ENDTRY.

5.2. 方法二:批量设置列标题

DATA: lt_cols TYPE salv_t_column_ref,
      ls_col  LIKE LINE OF lt_cols.

" 获取所有列引用
lt_cols = lr_columns->get( ).

" 循环设置列标题
LOOP AT lt_cols INTO ls_col.
  CASE ls_col-columnname.
    WHEN 'MATNR'.
      ls_col-r_column->set_short_text( '物料编号' ).
    WHEN 'MAKTX'.
      ls_col-r_column->set_short_text( '物料描述' ).
    WHEN 'WERKS'.
      ls_col-r_column->set_short_text( '工厂' ).
    WHEN 'LGORT'.
      ls_col-r_column->set_short_text( '库存地点' ).
    " 添加更多字段...
  ENDCASE.
ENDLOOP.

5.3. 方法三:使用字典结构的文本标识

如果内表基于DDIC结构,可以使用字段的文本标识:

" 首先确保列对象已获取
lr_columns = gr_table->get_columns( ).

" 设置使用字段文本作为列标题
lr_columns->set_use_key_as_header( abap_false ).  " 不使用技术名称
lr_columns->set_key_fixation( abap_false ).

5.4. 完整示例

REPORT z_change_column_headers.

DATA: gt_data TYPE TABLE OF makt,  " 物料描述表
      gr_table TYPE REF TO cl_salv_table.

START-OF-SELECTION.
  " 获取示例数据
  SELECT * FROM makt INTO TABLE gt_data UP TO 20 ROWS
    WHERE spras = sy-langu.

  TRY.
      " 创建ALV表
      cl_salv_table=>factory(
        IMPORTING
          r_salv_table = gr_table
        CHANGING
          t_table      = gt_data
      ).

      " 获取列对象
      DATA(lr_columns) = gr_table->get_columns( ).
      
      " 设置列优化
      lr_columns->set_optimize( abap_true ).
      
      " 修改特定列标题
      DATA(lr_column) TYPE REF TO cl_salv_column_table.
      
      TRY.
          lr_column ?= lr_columns->get_column( 'MATNR' ).
          lr_column->set_short_text( '物料号' ).
          lr_column->set_long_text( '物料主编号' ).
        CATCH cx_salv_not_found.
      ENDTRY.
      
      TRY.
          lr_column ?= lr_columns->get_column( 'MAKTX' ).
          lr_column->set_short_text( '描述' ).
          lr_column->set_long_text( '物料描述文本' ).
        CATCH cx_salv_not_found.
      ENDTRY.
      
      " 显示ALV表
      gr_table->display( ).

    CATCH cx_salv_msg INTO DATA(lx_error).
      MESSAGE lx_error->get_text( ) TYPE 'E'.
  ENDTRY.

5.5. 注意事项

  1. 字段名大小写:SALV中字段名通常是大写的,确保使用大写字段名
  2. 错误处理:使用TRY-CATCH处理可能不存在的字段
  3. 文本长度:短文本(short_text)通常限制在10个字符内,中等文本(medium_text)约20个字符,长文本(long_text)可更长
  4. 性能考虑:对于大量列,使用方法二的批量处理更高效

通过这些方法,可以轻松地将ALV表格中的技术字段名替换为更有业务意义的描述性标题。

用这个 cl_salv_table=>factory( IMPORTING r_salv_table = gr_table CHANGING t_table = gt_data ).输出gt_data的数据时如果不想要输出gt_data中的全部字段 ,该怎么处理

6. 在 CL_SALV_TABLE 中控制输出字段(隐藏不需要的字段)

当使用 CL_SALV_TABLE=>FACTORY 输出数据时,可以通过以下几种方法控制显示的字段,隐藏不需要的列:

6.1. 方法一:使用 set_visible 隐藏特定列

DATA: lr_columns TYPE REF TO cl_salv_columns_table,
      lr_column  TYPE REF TO cl_salv_column_table.

" 获取列对象
lr_columns = gr_table->get_columns( ).

" 隐藏不需要的列
TRY.
    lr_column ?= lr_columns->get_column( 'FIELD_TO_HIDE1' ). " 要隐藏的字段名
    lr_column->set_visible( abap_false ).                   " 设置为不可见
  CATCH cx_salv_not_found.
ENDTRY.

TRY.
    lr_column ?= lr_columns->get_column( 'FIELD_TO_HIDE2' ).
    lr_column->set_visible( abap_false ).
  CATCH cx_salv_not_found.
ENDTRY.

6.2. 方法二:使用 set_technical 隐藏技术字段

" 获取列对象
lr_columns = gr_table->get_columns( ).

" 将字段标记为技术字段(会自动隐藏)
TRY.
    lr_column ?= lr_columns->get_column( 'TECH_FIELD' ).
    lr_column->set_technical( abap_true ).  " 设置为技术字段
  CATCH cx_salv_not_found.
ENDTRY.

6.3. 方法三:预先处理数据(推荐)

最彻底的方法是只选择需要的字段到工作区中:

" 1. 定义只包含所需字段的结构
TYPES: BEGIN OF ty_output,
         matnr TYPE matnr,  " 物料编号
         maktx TYPE maktx,  " 物料描述
         meins TYPE meins,  " 单位
         " 只添加需要的字段...
       END OF ty_output.

" 2. 定义内表
DATA: gt_output TYPE TABLE OF ty_output.

" 3. 从原始数据中只选择需要的字段
LOOP AT gt_data ASSIGNING FIELD-SYMBOL(<fs_data>).
  APPEND VALUE #(
    matnr = <fs_data>-matnr
    maktx = <fs_data>-maktx
    meins = <fs_data>-meins
    " 只赋值需要的字段...
  ) TO gt_output.
ENDLOOP.

" 4. 使用处理后的数据输出ALV
cl_salv_table=>factory(
  IMPORTING
    r_salv_table = gr_table
  CHANGING
    t_table      = gt_output  " 使用只包含需要字段的内表
).

6.4. 方法四:使用字段目录控制显示

DATA: lt_fieldcat TYPE salv_t_fieldcat,
      ls_fieldcat LIKE LINE OF lt_fieldcat.

" 获取字段目录
lt_fieldcat = cl_salv_controller_metadata=>get_lvc_fieldcatalog(
  r_columns      = gr_table->get_columns( )
  r_aggregations = gr_table->get_aggregations( )
).

" 修改字段属性
LOOP AT lt_fieldcat INTO ls_fieldcat.
  CASE ls_fieldcat-fieldname.
    WHEN 'FIELD_TO_HIDE1' OR 'FIELD_TO_HIDE2'.
      ls_fieldcat-no_out = abap_true.  " 设置为不输出
  ENDCASE.
  MODIFY lt_fieldcat FROM ls_fieldcat.
ENDLOOP.

" 应用修改后的字段目录
cl_salv_controller_metadata=>set_lvc_fieldcatalog(
  r_columns      = gr_table->get_columns( )
  t_fieldcatalog = lt_fieldcat
).

6.5. 完整示例

REPORT z_selective_alv_columns.

DATA: gt_mara TYPE TABLE OF mara,  " 原始数据(包含所有字段)
      gt_output TYPE TABLE OF ty_output,
      gr_table TYPE REF TO cl_salv_table.

" 定义输出结构
TYPES: BEGIN OF ty_output,
         matnr TYPE mara-matnr,  " 物料编号
         mtart TYPE mara-mtart,  " 物料类型
         meins TYPE mara-meins,  " 基本单位
       END OF ty_output.

START-OF-SELECTION.
  " 获取原始数据
  SELECT * FROM mara INTO TABLE gt_mara UP TO 20 ROWS.

  " 方法三:预先处理数据(推荐)
  LOOP AT gt_mara ASSIGNING FIELD-SYMBOL(<fs_mara>).
    APPEND VALUE #(
      matnr = <fs_mara>-matnr
      mtart = <fs_mara>-mtart
      meins = <fs_mara>-meins
    ) TO gt_output.
  ENDLOOP.

  TRY.
      " 创建ALV表
      cl_salv_table=>factory(
        IMPORTING
          r_salv_table = gr_table
        CHANGING
          t_table      = gt_output
      ).

      " 方法一:额外隐藏不需要的列(如果需要)
      DATA(lr_columns) = gr_table->get_columns( ).
      TRY.
          lr_column ?= lr_columns->get_column( 'MEINS' ).  " 假设还要隐藏单位字段
          lr_column->set_visible( abap_false ).
        CATCH cx_salv_not_found.
      ENDTRY.

      " 设置列优化
      lr_columns->set_optimize( abap_true ).

      " 显示ALV表
      gr_table->display( ).

    CATCH cx_salv_msg INTO DATA(lx_error).
      MESSAGE lx_error->get_text( ) TYPE 'E'.
  ENDTRY.

6.6. 方法比较

方法

优点

缺点

set_visible

简单直接

数据仍然存在于内表中

set_technical

自动隐藏技术字段

仅适用于真正技术字段

预先处理数据

最干净,减少内存使用

需要额外编码

字段目录

最灵活

最复杂

推荐做法:对于简单情况使用方法一,对于复杂报表推荐使用方法三(预先处理数据),这样不仅控制显示,还能提高性能减少内存使用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值