Skip to Content
Personal Insights
Author's profile photo Raghavan Kathamuthu

Sample ABAP ALV report with editable fields with user command without join condition

Introduction:

Hope everyone is well. I am PP functional consultant gathering ABAP technical Knowledge. In ABAP for self learning we need more sample program to get clarification on understanding things better. In SAP blog the availability of sample program is less. So I am writing this.

Main Part

This program will fetch the material details details and changing the values in alv will update the ztable.

Below is the program.

REPORT zr.

TYPES: BEGIN OF ty_final,
  matnr TYPE mara-matnr,
  maktx TYPE makt-maktx,
  cellcolor TYPE lvc_t_scol,
  END OF ty_final.

TYPES: BEGIN OF ty_mara,
  matnr TYPE mara-matnr,
  END OF ty_mara.

TYPES : BEGIN OF ty_makt,
  matnr TYPE makt-matnr,
  maktx TYPE makt-maktx,
  END OF ty_makt.

DATA: it_final TYPE TABLE OF ty_final,
  wa_final TYPE ty_final,
  it_mara TYPE TABLE OF ty_mara,
  wa_mara TYPE ty_mara,
  it_makt TYPE TABLE OF ty_makt,
  wa_makt TYPE ty_makt,
  matnr TYPE mara-matnr,
  lv_index   TYPE sy-tabix,
  wa_cellcolor TYPE lvc_s_scol, "  for cell color
  wa_layout TYPE slis_layout_alv,
  ref1 TYPE REF TO cl_gui_alv_grid, " to capture changes in alv
  it_zfinal TYPE TABLE OF ty_final, "temproary final internal table
  wa_zfinal TYPE ty_final,
  wa_zzfinal TYPE ty_makt, "  temproary work area 
*to move changed values in alv
  it_fieldcat TYPE slis_t_fieldcat_alv, "  for Alv
  wa_fieldcat TYPE slis_fieldcat_alv.


SELECTION-SCREEN BEGIN OF BLOCK a.
  SELECT-OPTIONS: s_matnr FOR matnr.
  SELECTION-SCREEN END OF BLOCK a.

START-OF-SELECTION.
      PERFORM : getdata.
      PERFORM: f_build_layout .
      PERFORM: dispaly.

FORM getdata .

    SELECT matnr FROM mara INTO TABLE it_mara WHERE matnr IN S_matnr.
    IF it_mara IS NOT INITIAL.
    SELECT matnr maktx FROM makt INTO TABLE it_makt
    FOR ALL ENTRIES IN it_mara WHERE matnr = it_mara-matnr AND spras = 'EN'.
    ENDIF.
* moving values from temproary internal table to final internal table
    LOOP AT it_mara INTO wa_mara.
    wa_final-matnr = wa_mara-matnr.
    READ TABLE it_makt INTO wa_makt WITH KEY matnr = wa_mara-matnr.
    wa_final-maktx = wa_makt-maktx.
    wa_final-matnr = wa_mara-matnr.
    APPEND wa_final TO it_final.
    ENDLOOP.

IF it_final IS INITIAL.
  MESSAGE 'no values' TYPE 'I'.
  LEAVE TO CURRENT TRANSACTION.
  ENDIF.
*color code for the cells based on condition
  LOOP AT it_FINAL INTO wa_FINAL.
    lv_index = sy-tabix.
    IF  wa_final-matnr+0(1) = '0'.
    wa_cellcolor-fname = 'MATNR'.
    wa_cellcolor-color-col = 6.
    wa_cellcolor-color-int = '1'.
    wa_cellcolor-color-inv = '0'.
    APPEND wa_cellcolor TO wa_FINAL-cellcolor.
    CLEAR: wa_cellcolor.
    MODIFY it_final FROM wa_final INDEX lv_index TRANSPORTING cellcolor.
    CLEAR wa_final.
      ENDIF.
   ENDLOOP.
ENDFORM.
END-OF-SELECTION.

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program                = sy-repid
      i_callback_pf_status_set          = 'PF_STATUS'
      i_callback_user_command           = 'USER_COMMAND'
      is_layout                         = wa_layout
      it_fieldcat                       = it_fieldcat
     TABLES
       t_outtab                          = it_final
    EXCEPTIONS
      PROGRAM_ERROR                     = 1
      OTHERS                            = 2
             .
   IF sy-subrc <> 0.
* Implement suitable error handling here
   ENDIF.
*appending values to fieldcatalogue.
FORM dispaly .

  wa_fieldcat-tabname = 'IT_FINAL'.
  wa_fieldcat-fieldname = 'MATNR'.
  wa_fieldcat-seltext_m = 'Material'.

  APPEND wa_fieldcat TO it_fieldcat.
  CLEAR: wa_fieldcat.

  wa_fieldcat-tabname = 'IT_FINAL'.
  wa_fieldcat-fieldname = 'MAKTX'.
  wa_fieldcat-seltext_m = 'Description'.
  wa_fieldcat-edit ='X'.

  APPEND wa_fieldcat TO it_fieldcat.
  CLEAR: wa_fieldcat.
*appending values form final internal table to
* temproary final table for data comparision
  it_zfinal[] = it_final[].

ENDFORM.

*syntax for declarin usercommand
FORM user_command USING p_ucomm TYPE sy-ucomm
                        p_selfield TYPE slis_selfield.
CASE p_ucomm.
    WHEN '&IC1'.
      LOOP AT it_final INTO wa_final.
      READ TABLE it_final INTO wa_final WITH KEY matnr = wa_final-matnr.
      WRITE: / wa_final-matnr.
      ENDLOOP.

    WHEN 'SAVE'.

      CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR' "Capturing changes in ALV
      IMPORTING
        e_grid = ref1.
      CALL METHOD ref1->check_changed_data.
*moving changed value into ztable on saving
LOOP AT it_final INTO wa_final.
  READ TABLE it_zfinal INTO wa_zfinal WITH KEY matnr = wa_final-matnr.
  IF wa_zfinal-matnr = wa_final-matnr AND wa_zfinal-maktx NE wa_final-maktx.
    MOVE-CORRESPONDING wa_final TO wa_zzfinal.
    MODIFY zfinal FROM wa_zzfinal.
  ENDIF.
ENDLOOP.
    CLEAR: wa_final,wa_zfinal, wa_zzfinal.
ENDCASE.
ENDFORM.
*se41 create, generate, activate the buttons and assing it.
FORM pf_status USING rt_extab TYPE slis_t_extab.
  SET PF-STATUS 'ZPF_STATUS'.
ENDFORM.
*color code building for FM
FORM f_build_layout .
  CLEAR wa_layout.
  wa_layout-colwidth_optimize = 'X'.
  wa_layout-coltab_fieldname = 'CELLCOLOR'.

ENDFORM.

 

Output is like below

Here the second field is editable and I have changed it and saved it and it got updated in zfinal table.

Conclusion

Hope this may helpful.

It will be helpful if you share your thoughts like Ron in https://blogs.sap.com/2023/04/20/abap-sample-report-program-with-join-condition-and-using-cl_salv_table-class/

Have a look into the below.

https://erproof.com/abap/sap-abap-training/alv-report-in-sap-abap/

Assigned Tags

      1 Comment
      You must be Logged on to comment or reply to a post.
      Author's profile photo Matthew Billingham
      Matthew Billingham

      You are using quite old ABAP techniques.

      • Don't use forms and performs. Use classes and methods instead.
      • Have as few global variables as possible. Every one of your variables is global, which can lead to hard to find programming errors andyou don't have to worry about clearing the variables when you leave a subroutine. It is better to define a variable locally in two subroutines than to define once globally.
      • One of the exceptions to prefixing is that global variables should have some kind of indicator - like G_MATNR.
      • Don't use FOR ALL ENTRIES, use a join instead
      • Use INSERT ... INTO TABLE... rather than APPEND. Then if you change the table type, you won't have to change your program
      • Don't use TYPE TABLE. Use at least TYPE STANDARD TABLE.
      • Define it_zfinal as TYPE SORTED TABLE OF ty_final WITH NON-UNIQUE KEY matnr. (Possibly a UNIQUE KEY will work, in which case make it TYPE HASHED TABLE). Then your READ later in the code will be more efficient.
      • Use functional method calls, so instead of CALL METHOD ref1->check_changed_data use ref1->check_changed_data( ). And use a meaningful name, alv rather than ref1, for example.

      Here's a template - you'll notice I've correct misspelling and I've given the methods more meaningful names.

      Note, this isn't OO programming. It's using classes and methods in a procedural way.

      REPORT zr.
      
      DATA g_matnr TYPE matnr.
      
      SELECTION-SCREEN BEGIN OF BLOCK a.
      SELECT-OPTIONS: s_matnr FOR g_matnr.
      SELECTION-SCREEN END OF BLOCK a.
      
      CLASS lcl_main DEFINITION.
        PUBLIC SECTION.
          METHODS:
            get_data,
            build_layout,
            prepare_display,
            handle_command
              IMPORTING
                i_ucomm TYPE sy-ucomm,
            display.
        PRIVATE SECTION.
          " Define types here
          " Define variables needed by more than one method here - that doesn't include work areas!
      ENDCLASS.
      
      CLASS lcl_main IMPLEMENTATION.
      
        METHOD get_data.
          ...
        ENDMETHOD.
      
        METHOD build_layout.
          ...
        ENDMETHOD.
      
        METHOD prepare_display.
          ...
        ENDMETHOD.
      
      
        METHOD handle_command.
          CASE i_ucomm.
            ...
          ENDCASE.
        ENDMETHOD.
      
      
        METHOD display.
          CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
          ...
        ENDMETHOD.
      
      ENDCLASS.
      
      START-OF-SELECTION.
        DATA(main) = NEW lcl_main( ).
        main->get_data( ).
        main->build_layout( ).
        main->prepare_display( ).
      
      END-OF-SELECTION.
        main->display( ).
      
      FORM user_command USING p_ucomm TYPE sy-ucomm
                              p_selfield TYPE slis_selfield.
        main->handle_command( p_ucomm ).
      ENDFORM.
      
      FORM pf_status USING rt_extab TYPE slis_t_extab.
        SET PF-STATUS 'ZPF_STATUS'.
      ENDFORM.

      I would use CL_GUI_ALV_GRID directly rather than the function module, but I can understand that could be quite difficult for you at this stage.

      I strongly recommend you use the clean code repository for further guidance on good programming practice. https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md