SAP R/3 форум ABAP консультантов
Russian ABAP Developer's Club

Home - FAQ - Search - Memberlist - Usergroups - Profile - Log in to check your private messages - Register - Log in - English
Blogs - Weblogs News

Interactive Editable OO ALV grid with dynamic itab



 
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> ALV Grid / ALV Tree / ALV List
View previous topic :: View next topic  
Author Message
admin
Администратор
Администратор



Joined: 01 Sep 2007
Posts: 1639

PostPosted: Sun Apr 20, 2008 2:43 pm    Post subject: Interactive Editable OO ALV grid with dynamic itab Reply with quote

Interactive Editable OO ALV grid with dynamic itab,FCAT and ENTER key event trigger
Author: James hawthorne
Source: https: //wiki.sdn.sap.com/wiki/display/ABAP/Interactive+Editable+OO+ALV+grid+with+dynamic+itab%2CFCAT+and+ENTER+key+event+trigger

Hi everybody

Here's a more useful approach to ALV grid with OO using dynamic table, data NOT from DDIC, dynamic FCAT and how to get changed lines from the grid when ENTER key is pressed.

It's really not too dificult but I think this is more useful than the ever present SFLIGHT methods from the demos.

This also defines a subclass of cl_gui_alv_grid so you can access the protected attributes / methods of that class.

You don't need to add the class via SE24 -- done fron this ABAP.
When you run it click Edit for the first time.
After editing data press ENTER and the break point should bring you into the relevant method.

Code developed on NW2004S trial version but also works on rel 6.40 on a "Real" system.

The code should work without any changes on any system >=6.40.

All you need to do is to create a blank screen 100 via SE51 with a custom container on it called CCONTAINER1.

The rest of the code can just be uploaded into your system using the SE38 upload facility.

When running the program click on the EDIT button to enable the edit functionality of the grid.

Change your data and when you press ENTER you should get the break-point where you can see the original table and changed rows.

This program is actually quite general as it covers Dynamic tables, building a dynamic fcat where your table fields are NOT in the DDIC, intercepting the ENTER key via using an event, and accessing the protected attributes of the cl_gui_alv_grid by defining a subclass of this class in the abap.

I've seen various questions relating to all these functions but none in my view ever answers the questions in a simple manner. I hope this simple program will answer all these and show how using OO ALV is actually quite easy and people shouldn't be scared of using OO.

Have fun and award points if useful.

Cheers

Jimbo.

Code:

PROGRAM zdynfieldcat.
* Simple test of dynamic ITAB with user defined (not ddic) fields
* Build dynamic fcat
* use ALV grid to display and edit.

*When edit mode set to 1 toolbar gives possibility of adding and
*deleting rows.
*
*Define subclass of cl_gui_alv_grid so we can use protected attributes
*and methods.
*
** Add event handler to intercept user entering data and pressing the
*ENTER key.
*
* When enter key is pressed get actual value of NEW table (all rows)
* rather than just the changed data.
*
*use new RTTI functionality to retrieve internal table structure
*details.

* Create a blank screen 100 with a custom container called CCONTAINER1.
*
* James Hawthorne
*
INCLUDE <icon>.
* define any old internal structure NOT in DDIC
TYPES: BEGIN OF s_elements,
anyfield1(20) TYPE c,
anyfield2(20) TYPE c,
anyfield3(20) TYPE c,
anyfield4(20) TYPE c,
anyfield5(11) TYPE n,
END OF s_elements.
TYPES: lt_rows TYPE lvc_t_roid.

* Note new RTTI functionality allows field detail retrieval
* at runtime for dynamic tables.

DATA: wa_element TYPE s_elements ,
wa_data TYPE s_elements,
c_index TYPE sy-index,
c_dec2 TYPE s_elements-anyfield5,
wa_it_fldcat TYPE lvc_s_fcat,
it_fldcat TYPE lvc_t_fcat,
lr_rtti_struc TYPE REF TO cl_abap_structdescr, "RTTI
lt_comp TYPE cl_abap_structdescr=>component_table,"RTTI
ls_comp LIKE LINE OF lt_comp, "RTTI
zog LIKE LINE OF lr_rtti_struc->components, "RTTI
struct_grid_lset TYPE lvc_s_layo,
l_valid TYPE c,
new_table TYPE REF TO data.

FIELD-SYMBOLS: <dyn_table> TYPE STANDARD TABLE,
<actual_tab> TYPE STANDARD TABLE,
<fs1> TYPE ANY,
<fs2> TYPE table.

DATA: grid_container1 TYPE REF TO cl_gui_custom_container.
CLASS lcl_grid_event_receiver DEFINITION DEFERRED.
DATA: g_event_receiver TYPE REF TO lcl_grid_event_receiver.
DATA: ls_modcell TYPE lvc_s_modi,
stab TYPE REF TO data,
sdog TYPE s_elements. .

*----------------------------------------------------------------------*
*       CLASS lcl_grid_event_receiver DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_grid_event_receiver DEFINITION.
  PUBLIC SECTION.
    METHODS:
    handle_data_changed
    FOR EVENT data_changed OF cl_gui_alv_grid
    IMPORTING er_data_changed,

    toolbar FOR EVENT toolbar OF cl_gui_alv_grid
    IMPORTING e_object
    e_interactive,

    user_command FOR EVENT user_command OF cl_gui_alv_grid
    IMPORTING e_ucomm.

ENDCLASS.                    "lcl_grid_event_receiver DEFINITION

*-------------------------------------------------------------------*
*implementation of Grid event-handler class
*-------------------------------------------------------------------*
CLASS lcl_grid_event_receiver IMPLEMENTATION.

  METHOD handle_data_changed.
* code whatever required after data entry.
* various possibilites here as you can get back Cell(s) changed
* columns or the entire updated table.
* Data validation is also possible here.

    PERFORM check_data USING er_data_changed.

  ENDMETHOD.                    "handle_data_changed

*---------------------------------------------------------------------
* Method for handling all creation/modification calls to the toolbar
*---------------------------------------------------------------------
  METHOD toolbar.

    DATA : ls_toolbar TYPE stb_button.
*--------------------------------------------------------------------*
* Define Custom Button in the toolbar
*--------------------------------------------------------------------*
    CLEAR ls_toolbar.
    MOVE 0 TO ls_toolbar-butn_type.
    MOVE 'EDIT' TO ls_toolbar-function.
    MOVE space TO ls_toolbar-disabled.
    MOVE 'Edit' TO ls_toolbar-text.
    MOVE icon_change_text TO ls_toolbar-icon.
    MOVE 'Click2Edit' TO ls_toolbar-quickinfo.
    APPEND ls_toolbar TO e_object->mt_toolbar.

    CLEAR ls_toolbar.
    MOVE 0 TO ls_toolbar-butn_type.
    MOVE 'UPDA' TO ls_toolbar-function.
    MOVE space TO ls_toolbar-disabled.
    MOVE 'Update' TO ls_toolbar-text.
    MOVE icon_system_save TO ls_toolbar-icon.
    MOVE 'Click2Update' TO ls_toolbar-quickinfo.
    APPEND ls_toolbar TO e_object->mt_toolbar.

    CLEAR ls_toolbar.
    MOVE 0 TO ls_toolbar-butn_type.
    MOVE 'EXIT' TO ls_toolbar-function.
    MOVE space TO ls_toolbar-disabled.
    MOVE 'Exit' TO ls_toolbar-text.
    MOVE icon_system_end TO ls_toolbar-icon.
    MOVE 'Click2Exit' TO ls_toolbar-quickinfo.
    APPEND ls_toolbar TO e_object->mt_toolbar.

  ENDMETHOD.                    "toolbar

  METHOD user_command.

    CASE e_ucomm .
      WHEN 'EDIT'. "From Tool bar
        PERFORM set_input.
        PERFORM init_grid.

      WHEN 'UPDA'. "From Tool bar
        PERFORM refresh_disp.
        PERFORM update_table.

      WHEN 'EXIT'. "From Tool bar
        LEAVE PROGRAM.

    ENDCASE.

  ENDMETHOD.                    "user_command
ENDCLASS.                    "lcl_grid_event_receiver IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS zcltest DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS zcltest DEFINITION INHERITING FROM cl_gui_alv_grid.
*
* define this as a subclass so we can access the protected attributes
* of the superclass cl_gui_alv_grid

  PUBLIC SECTION.

    METHODS: constructor, disp_tab.

ENDCLASS.                    "zcltest DEFINITION

* need this now to instantiate object
* as we are using subclass rather than the main cl_gui_alv_grid.

CLASS zcltest IMPLEMENTATION.
  METHOD constructor.
    CALL METHOD super->constructor
      EXPORTING
        i_appl_events = 'X'
        i_parent      = grid_container1.
    .
  ENDMETHOD.                    "constructor

  METHOD disp_tab.
    FIELD-SYMBOLS: <outtab> TYPE STANDARD TABLE.
    BREAK-POINT 1.
* mt_outtab is the data table held as a protected attribute
* in class cl_gui_alv_grid.
    ASSIGN me->mt_outtab->* TO <outtab>. "Original data

* do whatever you want with <outtab>
* contains data BEFORE changes each time.
*
* Note that NEW (Changed) table has been obtained already by
* call to form check_data USING P_ER_DATA_CHANGED
* TYPE REF TO CL_ALV_CHANGED_DATA_PROTOCOL.
* Entered data is in table defined by <fs2>
* In this method you can compare original and changed data.
*
* Easier than messing around with individual cells.
* do what you want with data in <fs2> validate / update / merge etc

*
  ENDMETHOD.                    "disp_tab
ENDCLASS.                    "zcltest IMPLEMENTATION
DATA :

ok_code LIKE sy-ucomm,
save_ok LIKE sy-ucomm,
i4 TYPE int4,

* Container Object [grid_container]
* now created via method constructor
* in the subclass zcltest.

* Control Object [grid]

grid1 TYPE REF TO zcltest,

* Event-Handler Object [grid_handler]

grid_handler TYPE REF TO lcl_grid_event_receiver.

START-OF-SELECTION.

  CALL SCREEN 100.

*----------------------------------------------------------------------*
*  MODULE status_0100 OUTPUT
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.

* now display it as grid
  IF grid_container1 IS INITIAL.

    CREATE OBJECT grid_container1
    EXPORTING
    container_name = 'CCONTAINER1'.

    CREATE OBJECT grid1.
    BREAK-POINT 1.

    CREATE OBJECT grid_handler.
    SET HANDLER:
    grid_handler->user_command FOR grid1,
    grid_handler->toolbar FOR grid1,
    grid_handler->handle_data_changed FOR grid1.
    PERFORM create_dynamic_fcat.
    PERFORM create_dynamic_itab.
    PERFORM populate_dynamic_itab.
    PERFORM init_grid.
    PERFORM register_enter_event.

* set off ready for input initially
    i4 = 0.
    CALL METHOD grid1->set_ready_for_input
      EXPORTING
        i_ready_for_input = i4.

  ENDIF.

ENDMODULE.                    "status_0100 OUTPUT

*----------------------------------------------------------------------*
*  MODULE user_command_0100 INPUT
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
*
*PAI not needed in OO ALV anymore as User Commands are handled as events
*in method user_command.
*
*we can also get control if the Data entered and the ENTER is pressed by
*raising an event.
* Control then returns to method handle_data_changed.
*
*
*
ENDMODULE.                    "user_command_0100 INPUT

*&---------------------------------------------------------------------*
*&      Form  create_dynamic_fcat
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM create_dynamic_fcat.

* get structure of our user table for building field catalog
* Use the RTTI functionality

  lr_rtti_struc ?= cl_abap_structdescr=>describe_by_data( wa_data ).

* Build field catalog just use basic data here
* colour specific columns as well

  LOOP AT lr_rtti_struc->components INTO zog.
    c_index = c_index + 1.
    CLEAR wa_it_fldcat.
    wa_it_fldcat-fieldname = zog-name .
    wa_it_fldcat-datatype = zog-type_kind.
    wa_it_fldcat-inttype = zog-type_kind.
    wa_it_fldcat-intlen = zog-length.
    wa_it_fldcat-decimals = zog-decimals.
    wa_it_fldcat-lowercase = 'X'.
    IF c_index EQ 2.
      wa_it_fldcat-emphasize = 'C411'.
    ENDIF.
    IF c_index EQ 3.
      wa_it_fldcat-emphasize = 'C511'.
    ENDIF.
    APPEND wa_it_fldcat TO it_fldcat .
  ENDLOOP.

ENDFORM.                    "create_dynamic_fcat

*&---------------------------------------------------------------------*
*&      Form  create_dynamic_itab
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM create_dynamic_itab.
* Create dynamic internal table and assign to field sysmbol.
* Use dynamic field catalog just built.
  CALL METHOD cl_alv_table_create=>create_dynamic_table
    EXPORTING
      it_fieldcatalog = it_fldcat
    IMPORTING
      ep_table        = new_table.

  ASSIGN new_table->* TO <dyn_table>.

ENDFORM.                    "create_dynamic_itab

*&---------------------------------------------------------------------*
*&      Form  populate_dynamic_itab
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM populate_dynamic_itab.
* load up a line of the dynamic table
  c_dec2 = c_dec2 + 11.
  wa_element-anyfield1 = 'Tabbies'.
  wa_element-anyfield2 = 'ger.shepards'.
  wa_element-anyfield3 = 'White mice'.
  wa_element-anyfield4 = 'Any old text'.
  wa_element-anyfield5 = c_dec2.
  APPEND wa_element TO <dyn_table>.

ENDFORM.                    "populate_dynamic_itab

*&---------------------------------------------------------------------*
*&      Form  check_data
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_ER_DATA_CHANGED  text
*----------------------------------------------------------------------*
FORM check_data USING p_er_data_changed
TYPE REF TO cl_alv_changed_data_protocol.

* Get altered data back

  ASSIGN p_er_data_changed->mp_mod_rows TO <fs1>.

  stab = p_er_data_changed->mp_mod_rows.

  ASSIGN stab->* TO <fs2>.

  LOOP AT <fs2> INTO sdog.
* ALV grid display with altered data is now in <fs2>.
* do any extra processing you want here

  ENDLOOP.

* now display new table

  CALL METHOD grid1->disp_tab.

ENDFORM.                    "check_data

*&---------------------------------------------------------------------*
*&      Form  exit_program
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM exit_program.

  CALL METHOD grid_container1->free.

  CALL METHOD cl_gui_cfw=>flush.

  LEAVE PROGRAM.

ENDFORM.                    "exit_program

*&---------------------------------------------------------------------*
*&      Form  refresh_disp
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM refresh_disp.

  CALL METHOD grid1->refresh_table_display.

ENDFORM.                    "refresh_disp

*&---------------------------------------------------------------------*
*&      Form  update_table
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM update_table.

* The dynamic table here is the changed table read from the grid
* after user has changed it
* Data can be saved to DB or whatever.
  LOOP AT <dyn_table> INTO wa_element.

* do what you want with the data here
*
  ENDLOOP.

* switch off edit mode again for next function
  i4 = 0.
  CALL METHOD grid1->set_ready_for_input
    EXPORTING
      i_ready_for_input = i4.

ENDFORM.                    "update_table

*&---------------------------------------------------------------------*
*&      Form  set_input
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM set_input.

  i4 = 1.
  CALL METHOD grid1->set_ready_for_input
    EXPORTING
      i_ready_for_input = i4.

ENDFORM.                    "set_input

*&---------------------------------------------------------------------*
*&      Form  switch_input
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM switch_input.
  IF i4 = 1.
    i4 = 0.
  ELSE.
    i4 = 1.
  ENDIF.

  CALL METHOD grid1->set_ready_for_input
    EXPORTING
      i_ready_for_input = i4.

ENDFORM.                    "switch_input

*&---------------------------------------------------------------------*
*&      Form  init_grid
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM init_grid.

* Enabling the grid to edit mode,
  struct_grid_lset-edit = 'X'. "To enable editing in ALV
  struct_grid_lset-grid_title = 'Jimbos Test'.

  CALL METHOD grid1->set_table_for_first_display
    EXPORTING
      is_layout       = struct_grid_lset
    CHANGING
      it_outtab       = <dyn_table>
      it_fieldcatalog = it_fldcat.
ENDFORM.                    "init_grid

*&---------------------------------------------------------------------*
*&      Form  register_enter_event
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM register_enter_event.

  CALL METHOD grid1->register_edit_event
    EXPORTING
      i_event_id = cl_gui_alv_grid=>mc_evt_enter.
* Instantiate the event or it won't work.
  CREATE OBJECT g_event_receiver.
  SET HANDLER g_event_receiver->handle_data_changed FOR grid1.

ENDFORM.                    "register_enter_event
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> ALV Grid / ALV Tree / ALV List All times are GMT + 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


All product names are trademarks of their respective companies. SAPNET.RU websites are in no way affiliated with SAP AG.
SAP, SAP R/3, R/3 software, mySAP, ABAP, BAPI, xApps, SAP NetWeaver and any other are registered trademarks of SAP AG.
Every effort is made to ensure content integrity. Use information on this site at your own risk.