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

editable alv report

mohithvarma11
Explorer
0 Likes
887

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.

View Entire Topic
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.