Functional ALV系列 (05) - ALV 作为数据编辑界面

本篇介绍如何将 ALV 作为数据编辑界面来使用。关于 ALV 作为编辑界面的方法,我在 如何对SAP数据库表进行增删改查操作 这篇博文里已有详细说明,本文不再重复过程。本篇的目的是继续深入,讲解 ALV 作为界面的要点,并且提供一个通用的在 AVL 中修改表的程序。

FALV 作为编辑界面的要点

  • 编写一个能运行的用 ALV 显示数据的程序
  • 从 SAPLKKBL 拷贝 standard 工具栏到本程序,命名为 zstandard
  • 在工具栏中添加一个 Save 按钮
  • 设置 ALV 可编辑
  • 在程序中添加用于设置工具栏和处理用户命令的两个子例程并且进行应用

完成后的完整代码如下:

report  z_falv_009.

type-pools: slis.

data: gt_fieldcat type slis_t_fieldcat_alv,
      gs_fieldcat type slis_fieldcat_alv.

data:gt_spfli type standard table of spfli,
     gs_spfli like line of gt_spfli.

start-of-selection.
  perform frm_get_data.
  perform frm_disp_data.


*&---------------------------------------------------------------------*
*&      Form  frm_get_data
*&---------------------------------------------------------------------*
form frm_get_data.
  select * from spfli
    into table gt_spfli.
endform.                    "frm_get_data


*&---------------------------------------------------------------------*
*&      Form  frm_disp_data
*&---------------------------------------------------------------------*
form frm_disp_data.
  call function 'Z_FALV_FIELD_CATALOG'
    exporting
      it_output     = gt_spfli[]
    tables
      field_catalog = gt_fieldcat[].

  " make ALV editable if field is not a key
  loop at gt_fieldcat into gs_fieldcat.
    if gs_fieldcat-key = 'X'.
      gs_fieldcat-edit = ''.
    else.
      gs_fieldcat-edit = 'X'.
    endif.
    modify gt_fieldcat from gs_fieldcat.
    clear gs_fieldcat.
  endloop.

  call function 'REUSE_ALV_GRID_DISPLAY'
    exporting
      i_callback_program       = sy-repid
      i_callback_pf_status_set = 'FRM_GUI_STATUS'
      i_callback_user_command  = 'FRM_USER_COMMAND'
      it_fieldcat              = gt_fieldcat[]
    tables
      t_outtab                 = gt_spfli[].
endform.                    "frm_disp_data

*&---------------------------------------------------------------------*
*&      Form  frm_gui_status
*&---------------------------------------------------------------------*
form frm_gui_status using ex_tab type slis_t_extab.
  set pf-status 'ZSTANDARD'.
endform.                    "frm_status_set


*&---------------------------------------------------------------------*
*&      Form  frm_user_command
*&---------------------------------------------------------------------*
form frm_user_command using p_ucomm    type sy-ucomm        " user command
                            p_selfield type slis_selfield.  " select field

  data: r_alv_grid type ref to cl_gui_alv_grid.

  case p_ucomm.
    when '&SAVE'.
      if r_alv_grid is initial.
        call function 'GET_GLOBALS_FROM_SLVC_FULLSCR'
          importing
            e_grid = r_alv_grid.
      endif.

      if not r_alv_grid is initial.
        call method r_alv_grid->check_changed_data.
      endif.

      p_selfield-refresh = 'X'.

      " save data to db
      update spfli from table gt_spfli.

      if sy-subrc is initial.
        message 'Data was saved successfully.' type 'S'.
      else.
        message 'Data was not saved, errors ocured.' type 'S'.
      endif.
  endcase.
endform.                    "frm_user_command

在拷贝的工具栏中添加 Save 按钮(细节略)

设置 ALV 可编辑:

设置工具栏:

处理用户的命令:

锁对象

为了保证多用户操作数据的一致性问题,数据保存到数据库需要添加锁对象并且在程序中调用 FM 来加锁和释放。我的另一篇博文 ABAP - 锁对象及使用方法描述了如何创建和应用锁对象。在程序中应用锁对象的方法如下:

form frm_user_command using p_ucomm    type sy-ucomm        " user command
                            p_selfield type slis_selfield.  " select field

  data: r_alv_grid type ref to cl_gui_alv_grid.

  case p_ucomm.
    when '&SAVE'.
      if r_alv_grid is initial.
        call function 'GET_GLOBALS_FROM_SLVC_FULLSCR'
          importing
            e_grid = r_alv_grid.
      endif.

      if not r_alv_grid is initial.
        call method r_alv_grid->check_changed_data.
      endif.

      p_selfield-refresh = 'X'.

      " save data to db

      call function 'ENQUEUE_EZ_SPFLI'
        exporting
          mode_spfli     = 'E'
          mandt          = sy-mandt
          _scope         = '2'
        exceptions
          foreign_lock   = 1
          system_failure = 2
          others         = 3.

      if sy-subrc <> 0.
        message id sy-msgid type sy-msgty number sy-msgno
                with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
      else.
        update spfli from table gt_spfli.

        if sy-subrc is initial.
          message 'Data was saved successfully.' type 'S'.
        else.
          message 'Data was not saved, errors ocured.' type 'S'.
        endif.

        call function 'DEQUEUE_EZ_SPFLI'
          exporting
            mode_spfli = 'E'
            mandt      = sy-mandt
            _scope     = '3'.
      endif.
  endcase.
endform.                    "frm_user_command

ALV 实现通用表编辑界面

通过动态编程,我们也可以实现对任意表的编辑和保存。新的知识点主要是利用 ABAP 的动态编程语法。在选择屏幕中,输入表名和选择条件:


SAP 展示选择的数据,双击其中一行,在对话框中显示该行:


在弹出的对话矿中,编辑数据后回到主界面,点击保存按钮将数据保存到数据库。

下面是完整代码:

report  z_falv_010.

type-pools: slis.

data: gt_fieldcat type slis_t_fieldcat_alv,
      gs_fieldcat type slis_fieldcat_alv.

data: gt_index   type standard table of i with header line,
      table_name like dd02l-tabname.

data: report_id like sy-repid.

data: dy_table   type ref to data,
      dy_temptab type ref to data, " temporary table for saving to db
      dy_line    type ref to data.

field-symbols: <dyn_table>    type standard table,
               <dyn_wa>       type any,
               <dyn_field>    type any,
               <dyn_tab_temp> type standard table.

*------------------------------------------------------
* Screen
*------------------------------------------------------
parameters: p_tab(30) type c obligatory, " table name
            p_cri     type string.       " criteria

*------------------------------------------------------
* Events
*------------------------------------------------------
start-of-selection.
  report_id = sy-repid.
  table_name = p_tab. " table name

  perform frm_check_if_table_exists using table_name.
  perform frm_get_data.
  perform frm_disp_data.


*&---------------------------------------------------------------------*
*&      Form  frm_check_if_table_exists
*&---------------------------------------------------------------------*
form frm_check_if_table_exists using p_tabname like dd02l-tabname.
  data: l_tabname like dd02l-tabname.
  select single tabname from dd02l into l_tabname
    where tabname = table_name.

  if not sy-subrc is initial.
    message ' No table was found.' type 'E'.
    leave program.
  endif.
endform.                    "frm_check_if_table_exists

*&---------------------------------------------------------------------*
*&      Form  frm_get_data
*&---------------------------------------------------------------------*
form frm_get_data.
  " Create internal table dynamically from table name input in selection screen
  create data dy_table type standard table of (table_name).
  assign dy_table->* to <dyn_table>.

  " Create another temporary table
  create data dy_temptab type standard table of (table_name).
  assign dy_temptab->* to <dyn_tab_temp>.

  " Create work area for the table
  create data dy_line like line of <dyn_table>.
  assign dy_line->* to <dyn_wa>.

  select * from (table_name) into table <dyn_table>
    where (p_cri).

  refresh <dyn_tab_temp>.
endform.                    "frm_get_data


*&---------------------------------------------------------------------*
*&      Form  frm_disp_data
*&---------------------------------------------------------------------*
form frm_disp_data.
  sort gt_fieldcat by col_pos.

  " Display table in ALV
  call function 'REUSE_ALV_LIST_DISPLAY'
    exporting
      i_callback_program       = report_id
      i_structure_name         = table_name
      i_callback_user_command  = 'FRM_USER_COMMAND'
      i_callback_pf_status_set = 'FRM_SET_PF_STATUS'
    tables
      t_outtab                 = <dyn_table>
    exceptions
      program_error            = 1
      others                   = 2.
endform.                    "frm_disp_data


*&---------------------------------------------------------------------*
*&      Form  frm_set_pf_status
*&---------------------------------------------------------------------*
form frm_set_pf_status using rt_extab type slis_t_extab.
  set pf-status 'Z_STANDARD'.
endform.                    "SET_PF_STATUS


*&---------------------------------------------------------------------*
*&      Form  frm_user_command
*&---------------------------------------------------------------------*
form frm_user_command using r_ucomm     like sy-ucomm
                            rs_selfield type slis_selfield.

  data: li_tab type ref to data,
        l_line type ref to data.


  field-symbols:<l_tab> type table,
                <l_wa>  type any.

  " Create table
  create data li_tab type standard table of (table_name).
  assign li_tab->* to <l_tab>.

  " Create work area
  create data l_line like line of <l_tab>.
  assign l_line->* to <l_wa>.

  case r_ucomm.
      " When a record is selected
    when '&IC1'.
      " Read the selected record
      read table <dyn_table> assigning <dyn_wa> index rs_selfield-tabindex.
      if sy-subrc = 0.
        " Store the record in an internal table
        append <dyn_wa> to <l_tab>.

        " Fetch the field catalog info
        call function 'REUSE_ALV_FIELDCATALOG_MERGE'
          exporting
            i_program_name         = report_id
            i_structure_name       = table_name
          changing
            ct_fieldcat            = gt_fieldcat
          exceptions
            inconsistent_interface = 1
            program_error          = 2
            others                 = 3.
        if sy-subrc = 0.
          " Make all the fields input enabled except key fields
          gs_fieldcat-input = 'X'.
          modify gt_fieldcat from gs_fieldcat transporting input
          where key is initial.
        endif.

        " Display the record for editing purpose
        call function 'REUSE_ALV_LIST_DISPLAY'
          exporting
            i_callback_program    = report_id
            i_structure_name      = table_name
            it_fieldcat           = gt_fieldcat
            i_screen_start_column = 10
            i_screen_start_line   = 15
            i_screen_end_column   = 200
            i_screen_end_line     = 20
          tables
            t_outtab              = <l_tab>
          exceptions
            program_error         = 1
            others                = 2.

        if sy-subrc = 0.
          " Read the modified data
          read table <l_tab> index 1 into <l_wa>.

          " If the record is changed then track its index no.
          " and populate it in an internal table for future action
          if sy-subrc = 0 and <dyn_wa> <> <l_wa>.
            <dyn_wa> = <l_wa>.
            gt_index = rs_selfield-tabindex.
            append gt_index.
          endif.
        endif.
      endif.

    when 'SAVE'.
      " Sort the index table
      sort gt_index.

      " Delete all duplicate records
      delete adjacent duplicates from gt_index.

      loop at gt_index.
        " Find out the changes in the internal table
        " and populate these changes in another internal table
        read table <dyn_table> assigning <dyn_wa> index gt_index.
        if sy-subrc = 0.
          append <dyn_wa> to <dyn_tab_temp>.
        endif.
      endloop.

      " Lock the table
      call function 'ENQUEUE_E_TABLE'
        exporting
          mode_rstable   = 'E'
          tabname        = table_name
        exceptions
          foreign_lock   = 1
          system_failure = 2
          others         = 3.
      if sy-subrc = 0.
        " Modify the database table with the changes
        modify (table_name) from table <dyn_tab_temp>.
        refresh <dyn_tab_temp>.

        " Unlock the table
        call function 'DEQUEUE_E_TABLE'
          exporting
            mode_rstable = 'E'
            tabname      = table_name.

        message 'Data was saved successfully' type 'S'.
      endif.
  endcase.

  rs_selfield-refresh = 'X'.
endform.                    "user_command

源代码

05-Edit data in ALV

参考

ALV-Editing and saving the edited values in Database(OOPS)

在SAP项目上,常见的功能开发说明书(Functional Specification,简称FS)包括以下几种: 1. 数据字典(DDIC)FS:描述数据字典对象的设计和定义,包括表、数据元素、域、视图等。 2. 报表(ALV报表、SAP Query、ABAP List Viewer)FS:描述报表的设计和开发,包括字段、排序、筛选、计算等功能。 3. 用户界面(屏幕、菜单、工具栏)FS:描述用户界面的设计和开发,包括屏幕布局、输入输出字段、屏幕流程等。 4. 数据迁移(LSMW、BDC)FS:描述数据迁移的设计和开发,包括数据转换规则、文件格式、字段映射等。 5. 工作流(SAP Workflow)FS:描述工作流的设计和开发,包括流程步骤、条件、触发器、代理等。 6. 批处理作业(SAP Background Job)FS:描述批处理作业的设计和开发,包括作业流程、调度时间、参数设置等。 7. 接口(RFC、IDoc、Web服务)FS:描述接口的设计和开发,包括数据结构、传输方式、异常处理等。 8. 定制功能(ABAP开发)FS:描述定制功能的设计和开发,包括业务逻辑、数据处理、异常处理等。 这些是一些常见的SAP项目中编写FS功能开发说明书的示例。具体的FS内容和格式可能会根据项目和组织的要求而有所不同。FS的编写通常由功能顾问或开发人员负责,目的是明确功能需求、设计和开发细节,供开发人员参考和实施。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值