cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

editable alv report

mohithvarma11
Explorer
0 Likes
885

Hi Experts,

I have created editable alv report.

kindly check the code please let me know is this fine code or not.

thankyou.

code:

TYPE-POOLS: slis.

TABLES: ekpo.

SELECT-OPTIONS: s_ebeln FOR ekpo-ebeln.


DATA: it_ekpo TYPE STANDARD TABLE OF ekpo,
wa_ekpo TYPE ekpo.

DATA: it_fcat TYPE slis_t_fieldcat_alv,
wa_fcat TYPE slis_fieldcat_alv,
wa_layo TYPE slis_layout_alv.

*----------------------------------------------------------------------*
* START-OF-SELECTION
*----------------------------------------------------------------------*
START-OF-SELECTION.

PERFORM get_data.
PERFORM build_fieldcat.
PERFORM display_alv.

*----------------------------------------------------------------------*
* Get data
*----------------------------------------------------------------------*
FORM get_data.

SELECT *
FROM ekpo
INTO TABLE it_ekpo
UP TO 100 ROWS
where ekpo~ebeln IN s_ebeln.


ENDFORM.

*----------------------------------------------------------------------*
* Build field catalog
*----------------------------------------------------------------------*
FORM build_fieldcat.

CLEAR it_fcat.

" EBELN - not editable (key)
CLEAR wa_fcat.
wa_fcat-col_pos = 1.
wa_fcat-fieldname = 'EBELN'.
wa_fcat-seltext_l = 'PO Number'.
APPEND wa_fcat TO it_fcat.

" EBELP - not editable (key)
CLEAR wa_fcat.
wa_fcat-col_pos = 2.
wa_fcat-fieldname = 'EBELP'.
wa_fcat-seltext_l = 'Item'.
APPEND wa_fcat TO it_fcat.

" AEDAT - display only
CLEAR wa_fcat.
wa_fcat-col_pos = 3.
wa_fcat-fieldname = 'AEDAT'.
wa_fcat-seltext_l = 'Change Date'.
APPEND wa_fcat TO it_fcat.

" TXZ01 - editable
CLEAR wa_fcat.
wa_fcat-col_pos = 4.
wa_fcat-fieldname = 'TXZ01'.
wa_fcat-seltext_l = 'Short Text'.
wa_fcat-outputlen = 40.
wa_fcat-edit = 'X'.
APPEND wa_fcat TO it_fcat.

" MATNR - display only (you can make it editable if needed)
CLEAR wa_fcat.
wa_fcat-col_pos = 5.
wa_fcat-fieldname = 'MATNR'.
wa_fcat-seltext_l = 'Material'.
APPEND wa_fcat TO it_fcat.

" MENGE - editable
CLEAR wa_fcat.
wa_fcat-col_pos = 6.
wa_fcat-fieldname = 'MENGE'.
wa_fcat-seltext_l = 'Quantity'.
wa_fcat-edit = 'X'.
APPEND wa_fcat TO it_fcat.

" NETWR - editable
CLEAR wa_fcat.
wa_fcat-col_pos = 7.
wa_fcat-fieldname = 'NETWR'.
wa_fcat-seltext_l = 'Net Value'.
wa_fcat-edit = 'X'.
APPEND wa_fcat TO it_fcat.

CLEAR wa_layo.
wa_layo-colwidth_optimize = 'X'.

ENDFORM.

*----------------------------------------------------------------------*
* Display ALV
*----------------------------------------------------------------------*
FORM display_alv.

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = sy-repid
i_callback_user_command = 'USER_COMMAND'
is_layout = wa_layo
it_fieldcat = it_fcat
TABLES
t_outtab = it_ekpo
EXCEPTIONS
program_error = 1
OTHERS = 2.

IF sy-subrc <> 0.
MESSAGE 'Error in ALV display' TYPE 'E'.
ENDIF.

ENDFORM.

*----------------------------------------------------------------------*
* USER COMMAND
*----------------------------------------------------------------------*
FORM user_command USING r_ucomm TYPE sy-ucomm
r_selfield TYPE slis_selfield.

CASE r_ucomm.

WHEN '&DATA_SAVE'. " Triggered by Save (Ctrl+S) in ALV

PERFORM save_data.

" Refresh ALV after save
r_selfield-refresh = 'X'.

ENDCASE.

ENDFORM.

*----------------------------------------------------------------------*
* Save data: update ALL rows from internal table to EKPO
*----------------------------------------------------------------------*
FORM save_data.

" Update all entries based on primary key (EBELN+EBELP)
MODIFY ekpo FROM TABLE it_ekpo.

IF sy-subrc = 0.
COMMIT WORK.
MESSAGE 'All changed rows saved successfully' TYPE 'S'.
ELSE.
ROLLBACK WORK.
MESSAGE 'Error while updating EKPO' TYPE 'E'.
ENDIF.

ENDFORM.

Accepted Solutions (1)

Accepted Solutions (1)

nmirandaghn
Active Participant

I suggest using ABAP 7.5+ syntax:

Instead of this:

DATA: it_ekpo TYPE TABLE OF ekpo,
      it_fcat TYPE slis_t_fieldcat_alv,
      wa_fcat LIKE LINE OF it_fcat.

SELECT * FROM ekpo INTO TABLE it_ekpo WHERE ebeln IN s_ebeln.

CLEAR wa_fcat.
wa_fcat-fieldname = 'EBELN'.
wa_fcat-seltext_l = 'PO Number'.
APPEND wa_fcat TO it_fcat.
" ...more lines

Try this:

SELECT ebeln, ebelp, txz01, menge, netwr
  FROM ekpo
  WHERE ebeln IN @s_ebeln
  INTO TABLE @DATA(it_ekpo).

DATA(it_fcat) = VALUE slis_t_fieldcat_alv(
  ( fieldname = 'EBELN' seltext_l = 'PO Number' )
  ( fieldname = 'TXZ01' seltext_l = 'Text' edit = 'X' )
  ( fieldname = 'MENGE' seltext_l = 'Quantity' edit = 'X' )
).

Or you can use CL_SALV_TABLE :

TRY.
    cl_salv_table=>factory(
      IMPORTING r_salv_table = DATA(lo_alv)
      CHANGING  t_table      = it_ekpo ).

    " Auto-optimize column width
    lo_alv->get_columns( )->set_optimize( abap_true ).

    " Make specific columns editable
    lo_alv->extended_grid_api( )->editable_restricted( )->set_attributes_for_columnname(
      columnname = 'TXZ01'
      all_cells_input_enabled = abap_true ).

    lo_alv->display( ).

  CATCH cx_salv_error INTO DATA(lx_err).
    MESSAGE lx_err->get_text( ) TYPE 'E'.
ENDTRY.

Benefits:

  • No manual field catalog needed (auto-detects structure)
  • Cleaner, more maintainable code
  • Better aligned with S/4HANA standards
If you need complex editable grids with custom validations, CL_SALV_TABLE can be limiting. For those cases, CL_GUI_ALV_GRID is still more flexible.
 
Do you have any specific requirements for the report that are giving you trouble?
mohithvarma11
Explorer
0 Likes
how to save this? can you send me full code.
nmirandaghn
Active Participant
0 Likes

Complete CL_SALV_TABLE Example with Editable Columns

Modern ABAP 7.5+ Syntax | S/4HANA Compatible

Purpose: Display Purchase Order Items (EKPO) with editable columns using CL_SALV_TABLE and modern ABAP 7.5+ syntax

*&---------------------------------------------------------------------*
*& Report  Z_EKPO_EDITABLE_SALV
*&---------------------------------------------------------------------*
*& Purpose: Display Purchase Order Items (EKPO) with editable columns
*&          using CL_SALV_TABLE and modern ABAP 7.5+ syntax
*&---------------------------------------------------------------------*
REPORT z_ekpo_editable_salv.

*----------------------------------------------------------------------*
* Type Definitions
*----------------------------------------------------------------------*
TYPES: BEGIN OF ty_ekpo,
         ebeln TYPE ekpo-ebeln,  " Purchase Order Number
         ebelp TYPE ekpo-ebelp,  " PO Item Number
         aedat TYPE ekpo-aedat,  " Change Date
         txz01 TYPE ekpo-txz01,  " Short Text (Editable)
         matnr TYPE ekpo-matnr,  " Material Number
         menge TYPE ekpo-menge,  " Quantity (Editable)
         netwr TYPE ekpo-netwr,  " Net Value (Editable)
       END OF ty_ekpo.

*----------------------------------------------------------------------*
* Selection Screen
*----------------------------------------------------------------------*
SELECT-OPTIONS: s_ebeln FOR ekpo-ebeln.

*----------------------------------------------------------------------*
* Global Variables
*----------------------------------------------------------------------*
DATA: gt_ekpo TYPE STANDARD TABLE OF ty_ekpo,
      go_salv TYPE REF TO cl_salv_table,
      go_grid TYPE REF TO cl_gui_alv_grid.

*----------------------------------------------------------------------*
* Event Handler Class
*----------------------------------------------------------------------*
CLASS lcl_event_handler DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      " Handle toolbar button events
      on_user_command FOR EVENT added_function OF cl_salv_events
        IMPORTING e_salv_function,
      
      " Handle data changes in the grid
      on_data_changed FOR EVENT data_changed OF cl_gui_alv_grid
        IMPORTING er_data_changed.
ENDCLASS.

CLASS lcl_event_handler IMPLEMENTATION.
  
  METHOD on_user_command.
    CASE e_salv_function.
      WHEN 'SAVE'.
        " Trigger grid to flush changes to internal table
        CALL METHOD go_grid->check_changed_data.
        
        " Here you would implement your save logic
        " For standard tables like EKPO, use BAPIs or RAP instead of direct MODIFY
        MESSAGE 'Data saved successfully (use BAPI in production)' TYPE 'S'.
        
      WHEN OTHERS.
    ENDCASE.
  ENDMETHOD.
  
  METHOD on_data_changed.
    " This event is triggered when user modifies cells
    " You can add custom validations here
    DATA(lt_modified) = er_data_changed->mt_good_cells.
    
    LOOP AT lt_modified INTO DATA(ls_mod).
      " Add your validation logic here
      " Example: Check if quantity is positive
      IF ls_mod-fieldname = 'MENGE'.
        DATA(lv_value) = CONV menge_d( ls_mod-value ).
        IF lv_value <= 0.
          " Flag error
          er_data_changed->add_protocol_entry(
            i_msgid     = '00'
            i_msgno     = '001'
            i_msgty     = 'E'
            i_msgv1     = 'Quantity must be positive'
            i_fieldname = ls_mod-fieldname
            i_row_id    = ls_mod-row_id ).
        ENDIF.
      ENDIF.
    ENDLOOP.
  ENDMETHOD.
  
ENDCLASS.

*----------------------------------------------------------------------*
* START-OF-SELECTION
*----------------------------------------------------------------------*
START-OF-SELECTION.
  PERFORM select_data.
  PERFORM display_alv.

*----------------------------------------------------------------------*
* FORM select_data
*----------------------------------------------------------------------*
FORM select_data.
  
  " Modern inline declaration with host variable escaping (@)
  SELECT ebeln, ebelp, aedat, txz01, matnr, menge, netwr
    FROM ekpo
    WHERE ebeln IN @s_ebeln
    INTO TABLE @gt_ekpo
    UP TO 100 ROWS.
  
  IF sy-subrc <> 0.
    MESSAGE 'No data found' TYPE 'I'.
    LEAVE LIST-PROCESSING.
  ENDIF.
  
ENDFORM.

*----------------------------------------------------------------------*
* FORM display_alv
*----------------------------------------------------------------------*
FORM display_alv.
  
  TRY.
      " Create SALV instance using factory method
      cl_salv_table=>factory(
        IMPORTING
          r_salv_table = go_salv
        CHANGING
          t_table      = gt_ekpo ).
      
      " Configure columns
      DATA(lo_columns) = go_salv->get_columns( ).
      lo_columns->set_optimize( abap_true ).
      
      " Set column labels
      DATA(lo_column) = CAST cl_salv_column_table( lo_columns->get_column( 'EBELN' ) ).
      lo_column->set_long_text( 'Purchase Order' ).
      lo_column->set_medium_text( 'PO Number' ).
      lo_column->set_short_text( 'PO' ).
      
      lo_column = CAST cl_salv_column_table( lo_columns->get_column( 'EBELP' ) ).
      lo_column->set_long_text( 'Item Number' ).
      
      lo_column = CAST cl_salv_column_table( lo_columns->get_column( 'TXZ01' ) ).
      lo_column->set_long_text( 'Short Text' ).
      
      lo_column = CAST cl_salv_column_table( lo_columns->get_column( 'MENGE' ) ).
      lo_column->set_long_text( 'Quantity' ).
      
      lo_column = CAST cl_salv_column_table( lo_columns->get_column( 'NETWR' ) ).
      lo_column->set_long_text( 'Net Value' ).
      
      " Enable standard functions (toolbar buttons)
      DATA(lo_functions) = go_salv->get_functions( ).
      lo_functions->set_all( abap_true ).
      
      " Add custom SAVE button
      TRY.
          lo_functions->add_function(
            name     = 'SAVE'
            icon     = '@2L@'
            text     = 'Save'
            tooltip  = 'Save changes'
            position = if_salv_c_function_position=>right_of_salv_functions ).
        CATCH cx_salv_existing cx_salv_wrong_call.
      ENDTRY.
      
      " Register event handler for toolbar buttons
      DATA(lo_events) = go_salv->get_event( ).
      SET HANDLER lcl_event_handler=>on_user_command FOR lo_events.
      
      " *** ENABLE EDITING - Two approaches depending on your release ***
      
      " Approach 1: For SAP NetWeaver 7.56+ and S/4HANA (Official API)
      TRY.
          DATA(lo_editable) = go_salv->extended_grid_api( )->editable_restricted( ).
          
          " Make specific columns editable
          lo_editable->set_attributes_for_columnname(
            columnname              = 'TXZ01'
            all_cells_input_enabled = abap_true ).
          
          lo_editable->set_attributes_for_columnname(
            columnname              = 'MENGE'
            all_cells_input_enabled = abap_true ).
          
          lo_editable->set_attributes_for_columnname(
            columnname              = 'NETWR'
            all_cells_input_enabled = abap_true ).
          
        CATCH cx_salv_error INTO DATA(lx_error).
          " If extended_grid_api is not available, use Approach 2
          MESSAGE lx_error->get_text( ) TYPE 'I'.
      ENDTRY.
      
      " Display the grid
      go_salv->display( ).
      
    CATCH cx_salv_msg INTO DATA(lx_msg).
      MESSAGE lx_msg->get_text( ) TYPE 'E'.
  ENDTRY.
  
ENDFORM.

⚠️ Important Note

Direct modification of standard tables like EKPO is not recommended in S/4HANA due to data integrity concerns. Use appropriate BAPIs (e.g., BAPI_PO_CHANGE) or implement a RAP-based service for production scenarios.

Key Implementation Points

✓ Modern Syntax Usage

  • Inline declarations with DATA(variable) reduce code verbosity
  • Host variable escaping with @ is mandatory in S/4HANA SELECT statements
  • CAST operator for type casting

✓ Editable Columns

  • Uses the official extended_grid_api() method available in SAP NetWeaver 7.56+ and all S/4HANA releases
  • Only specific columns (TXZ01, MENGE, NETWR) are set as editable

✓ Event Handling

  • Custom toolbar button (SAVE) triggers the on_user_command event
  • The on_data_changed event allows validation before data is written to the internal table
nmirandaghn
Active Participant
0 Likes

*&---------------------------------------------------------------------*
*& Report Z_EKPO_EDITABLE_SALV
*&---------------------------------------------------------------------*
*& Purpose: Display Purchase Order Items (EKPO) with editable columns
*& using CL_SALV_TABLE and modern ABAP 7.5+ syntax
*&---------------------------------------------------------------------*
REPORT z_ekpo_editable_salv.

*----------------------------------------------------------------------*
* Type Definitions
*----------------------------------------------------------------------*
TYPES: BEGIN OF ty_ekpo,
ebeln TYPE ekpo-ebeln, " Purchase Order Number
ebelp TYPE ekpo-ebelp, " PO Item Number
aedat TYPE ekpo-aedat, " Change Date
txz01 TYPE ekpo-txz01, " Short Text (Editable)
matnr TYPE ekpo-matnr, " Material Number
menge TYPE ekpo-menge, " Quantity (Editable)
netwr TYPE ekpo-netwr, " Net Value (Editable)
END OF ty_ekpo.

*----------------------------------------------------------------------*
* Selection Screen
*----------------------------------------------------------------------*
SELECT-OPTIONS: s_ebeln FOR ekpo-ebeln.

*----------------------------------------------------------------------*
* Global Variables
*----------------------------------------------------------------------*
DATA: gt_ekpo TYPE STANDARD TABLE OF ty_ekpo,
go_salv TYPE REF TO cl_salv_table,
go_grid TYPE REF TO cl_gui_alv_grid.

*----------------------------------------------------------------------*
* Event Handler Class
*----------------------------------------------------------------------*
CLASS lcl_event_handler DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
" Handle toolbar button events
on_user_command FOR EVENT added_function OF cl_salv_events
IMPORTING e_salv_function,

" Handle data changes in the grid
on_data_changed FOR EVENT data_changed OF cl_gui_alv_grid
IMPORTING er_data_changed.
ENDCLASS.

CLASS lcl_event_handler IMPLEMENTATION.

METHOD on_user_command.
CASE e_salv_function.
WHEN 'SAVE'.
" Trigger grid to flush changes to internal table
CALL METHOD go_grid->check_changed_data.

" Here you would implement your save logic
" For standard tables like EKPO, use BAPIs or RAP instead of direct MODIFY
MESSAGE 'Data saved successfully (use BAPI in production)' TYPE 'S'.

WHEN OTHERS.
ENDCASE.
ENDMETHOD.

METHOD on_data_changed.
" This event is triggered when user modifies cells
" You can add custom validations here
DATA(lt_modified) = er_data_changed->mt_good_cells.

LOOP AT lt_modified INTO DATA(ls_mod).
" Add your validation logic here
" Example: Check if quantity is positive
IF ls_mod-fieldname = 'MENGE'.
DATA(lv_value) = CONV menge_d( ls_mod-value ).
IF lv_value <= 0.
" Flag error
er_data_changed->add_protocol_entry(
i_msgid = '00'
i_msgno = '001'
i_msgty = 'E'
i_msgv1 = 'Quantity must be positive'
i_fieldname = ls_mod-fieldname
i_row_id = ls_mod-row_id ).
ENDIF.
ENDIF.
ENDLOOP.
ENDMETHOD.

ENDCLASS.

*----------------------------------------------------------------------*
* START-OF-SELECTION
*----------------------------------------------------------------------*
START-OF-SELECTION.
PERFORM select_data.
PERFORM display_alv.

*----------------------------------------------------------------------*
* FORM select_data
*----------------------------------------------------------------------*
FORM select_data.

" Modern inline declaration with host variable escaping (@)
SELECT ebeln, ebelp, aedat, txz01, matnr, menge, netwr
FROM ekpo
WHERE ebeln IN @s_ebeln
INTO TABLE @gt_ekpo
UP TO 100 ROWS.

IF sy-subrc <> 0.
MESSAGE 'No data found' TYPE 'I'.
LEAVE LIST-PROCESSING.
ENDIF.

ENDFORM.

*----------------------------------------------------------------------*
* FORM display_alv
*----------------------------------------------------------------------*
FORM display_alv.

TRY.
" Create SALV instance using factory method
cl_salv_table=>factory(
IMPORTING
r_salv_table = go_salv
CHANGING
t_table = gt_ekpo ).

" Configure columns
DATA(lo_columns) = go_salv->get_columns( ).
lo_columns->set_optimize( abap_true ).

" Set column labels
DATA(lo_column) = CAST cl_salv_column_table( lo_columns->get_column( 'EBELN' ) ).
lo_column->set_long_text( 'Purchase Order' ).
lo_column->set_medium_text( 'PO Number' ).
lo_column->set_short_text( 'PO' ).

lo_column = CAST cl_salv_column_table( lo_columns->get_column( 'EBELP' ) ).
lo_column->set_long_text( 'Item Number' ).

lo_column = CAST cl_salv_column_table( lo_columns->get_column( 'TXZ01' ) ).
lo_column->set_long_text( 'Short Text' ).

lo_column = CAST cl_salv_column_table( lo_columns->get_column( 'MENGE' ) ).
lo_column->set_long_text( 'Quantity' ).

lo_column = CAST cl_salv_column_table( lo_columns->get_column( 'NETWR' ) ).
lo_column->set_long_text( 'Net Value' ).

" Enable standard functions (toolbar buttons)
DATA(lo_functions) = go_salv->get_functions( ).
lo_functions->set_all( abap_true ).

" Add custom SAVE button
TRY.
lo_functions->add_function(
name = 'SAVE'
icon = '@2L@'
text = 'Save'
tooltip = 'Save changes'
position = if_salv_c_function_position=>right_of_salv_functions ).
CATCH cx_salv_existing cx_salv_wrong_call.
ENDTRY.

" Register event handler for toolbar buttons
DATA(lo_events) = go_salv->get_event( ).
SET HANDLER lcl_event_handler=>on_user_command FOR lo_events.

" *** ENABLE EDITING - Two approaches depending on your release ***

" Approach 1: For SAP NetWeaver 7.56+ and S/4HANA (Official API)
TRY.
DATA(lo_editable) = go_salv->extended_grid_api( )->editable_restricted( ).

" Make specific columns editable
lo_editable->set_attributes_for_columnname(
columnname = 'TXZ01'
all_cells_input_enabled = abap_true ).

lo_editable->set_attributes_for_columnname(
columnname = 'MENGE'
all_cells_input_enabled = abap_true ).

lo_editable->set_attributes_for_columnname(
columnname = 'NETWR'
all_cells_input_enabled = abap_true ).

CATCH cx_salv_error INTO DATA(lx_error).
" If extended_grid_api is not available, use Approach 2
MESSAGE lx_error->get_text( ) TYPE 'I'.
ENDTRY.

" Approach 2: Access underlying CL_GUI_ALV_GRID (for older releases)
" Uncomment if Approach 1 fails
* DATA: lo_grid_adapter TYPE REF TO cl_salv_gui_table_ida.
* go_grid ?= go_salv->r_controller_r_table->r_model->r_grid.
*
* IF go_grid IS BOUND.
* " Set grid to input-ready mode
* go_grid->set_ready_for_input( 1 ).
*
* " Register data change event
* go_grid->register_edit_event( cl_gui_alv_grid=>mc_evt_modified ).
* SET HANDLER lcl_event_handler=>on_data_changed FOR go_grid.
*
* " Define which columns are editable via field catalog
* go_grid->get_frontend_fieldcatalog( IMPORTING et_fieldcatalog = DATA(lt_fcat) ).
* LOOP AT lt_fcat ASSIGNING FIELD-SYMBOL(<fs_fcat>).
* CASE <fs_fcat>-fieldname.
* WHEN 'TXZ01' OR 'MENGE' OR 'NETWR'.
* <fs_fcat>-edit = abap_true.
* ENDCASE.
* ENDLOOP.
* go_grid->set_frontend_fieldcatalog( lt_fcat ).
* ENDIF.

" Display the grid
go_salv->display( ).

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

ENDFORM.

Answers (0)