Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Dynamical Call of ALV - No data update

Former Member
0 Kudos
1,235

Hi,

I tried to use use the ALV dynamically. With dynamically I mean that I that I have diffrent data structures, depending what was selected by the user. The first call of the program is always correct. The data is displayed correctly. But when the data structure is changing, the ALV display is not updated. For a better understanding I post a extract of my coding:

<b>1. Creation of Container</b>
CREATE OBJECT g_custom_container
    EXPORTING               
      container_name              = 'PARENT_CONT'
    EXCEPTIONS
      cntl_error                  = 1
      cntl_system_error           = 2
      create_error                = 3
      lifetime_error              = 4
      lifetime_dynpro_dynpro_link = 5.
  IF sy-subrc <> 0.
    ASSERT 1 = 2.
  ENDIF.
......
<b>2.Creation of splitter container</b>
  CREATE OBJECT splitter
     EXPORTING
       parent            = g_custom_container
       rows              = 2
       columns           = 2
    EXCEPTIONS
      cntl_error        = 1
      cntl_system_error = 2
      OTHERS            = 3.
  IF sy-subrc <> 0.
    ASSERT 1 = 2.
  ENDIF.

container_2 = splitter->get_container(
                            row       = 1
                            column    = 2 ).

<b>3.Dynamic Creation of alv object</b>
  CREATE OBJECT go_grid
    EXPORTING
      i_parent = container_2.
  
<b>4. Get Fieldcatalogue</b>
  CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
    EXPORTING
      i_structure_name       = lv_structure_name
    CHANGING
      ct_fieldcat            = lt_fieldcat
    EXCEPTIONS
      inconsistent_interface = 1
      program_error          = 2
      OTHERS                 = 3.
  IF sy-subrc <> 0.
    ASSERT 1 = 2.
  ENDIF.

<b>5. Set table for first display</b>
  CALL METHOD go_grid->set_table_for_first_display
*    EXPORTING
*      i_structure_name = lv_structure_name
    CHANGING
      it_fieldcatalog  = lt_fieldcat
      it_outtab        = <lt_out_data>.

  CALL METHOD ls_alv_ref-alv_ref->refresh_table_display.
  CALL METHOD cl_gui_cfw=>flush.

Perhaps someone could help.....

Best Regards, Edgar

1 ACCEPTED SOLUTION

Former Member
0 Kudos
541

I assume here you want to display a different TABLE STRUCTURE not a separate GRID.

What I do is something like this

1) define a data structure which is the table you want to display E.g

types: begin of s_elements,

tabname type dd02l-tabname,

tabclass type dd02l-tabclass,

as4user type dd02l-as4user,

as4date type dd02l-as4date,

as4time type dd02l-as4time,

viewed(1) type c.

  • drop_down_handle type int4.

types: end of s_elements.

create data dref type s_elements.

assign dref->* to <fs>.

invoker = sy-repid.

*This field symbol <fs> will contain your

  • data structure from which you construct a field catalog.

*I do it by calling methods in a class.

2) define some variables which will be needed by generating a dynamic FCAT and table

***INCLUDE ZZ_JIMBO_INCL .

  • Generic editable ALV prog with dynamic structure and FCAT.

  • Jimbo 2007.

define col_name.

read table it_fldcat into wa_it_fldcat index &1.

wa_it_fldcat-coltext = &2.

wa_it_fldcat-outputlen = &3.

modify it_fldcat from wa_it_fldcat index &1.

end-of-definition.

data: dref type ref to data,

z_object type ref to zcl_alv_test,

invoker type sy-repid,

dy_line type ref to data,

dy_table type ref to data,

it_fldcat type lvc_t_fcat,

wa_it_fldcat type lvc_s_fcat,

i_gridtitle type lvc_title,

i_zebra type lvc_edit,

i_edit type lvc_edit,

wa_elements type s_elements,

row_number type lvc_s_roid,

lt_dropdown type lvc_t_drop,

ls_dropdown type lvc_s_drop.

field-symbols: <fs> type any,

<fs1> type any,

<dyn_table> type standard table,

<dyn_wa>.

3) Call a function module which builds the dynamic fcat , dynamic table and displays the grid

create data dref type s_elements.

assign dref->* to <fs>.

invoker = sy-repid.

i_gridtitle = 'HR ESS / ITS ZHR Tables - Double click to display'.

i_zebra = ' '.

i_edit = 'X '.

  • Function module performs these subroutines in this program

  • populate_dynamic_itab

  • name_columns

*

*

  • The other subroutines are performed from within the method calls to

  • class zcl_alv_test called from our generic screen program.

call function 'ZZ_CALL_SCREEN'

exporting

invoker = invoker

my_line = <fs>

i_gridtitle = i_gridtitle

i_edit = i_edit

i_zebra = i_zebra

importing

z_object = z_object

dy_table = dy_table.

form populate_dynamic_itab changing dy_table.

data tabx like dd02l-tabname.

assign dy_table->* to <dyn_table>.

create data dy_line like line of <dyn_table>.

assign dy_line->* to <dyn_wa>.

select *

from dd02l

into corresponding fields of table <dyn_table>

where tabname like 'ZHR%'.

*drop down box values of handle

*loop at <dyn_table> into wa_elements.

  • wa_elements-drop_down_handle = '1'.

  • modify <dyn_table> from wa_elements.

  • endloop.

endform.

function zz_call_screen.

*"----


""Local interface:

*" IMPORTING

*" REFERENCE(INVOKER) TYPE SYREPID

*" REFERENCE(MY_LINE) TYPE ANY

*" REFERENCE(I_GRIDTITLE) TYPE LVC_TITLE

*" REFERENCE(I_EDIT) TYPE LVC_EDIT

*" REFERENCE(I_ZEBRA) TYPE LVC_EDIT

*" EXPORTING

*" REFERENCE(DY_TABLE) TYPE REF TO DATA

*" REFERENCE(Z_OBJECT) TYPE REF TO ZCL_ALV_TEST

*"----


*

  • This function module instantiates a generic

  • ALV handling class

  • Builds a dynamic fcat from the structure passed in my_line

  • Creates a dynmic table using the FCAT created in the class

  • calls the alv display

  • Using this approach means that the calling programs

  • now no longer need a separate screen.

  • The dynamic table is now filled in the

  • form POPULATE_DYNAMIC_TABLE

  • which MUST exist in the calling program.

  • It is done this way as it is not praticable to have

  • a completely generic method of filling the dynamic table

  • as data selection depends on the application - could be via

  • joins etc etc.

  • Note that screen 100 and a standard interface (se41) are contained in

  • the main program of this function module.

  • screen just has one element a custom container called CCONTAINER1

  • status (SE41) is just a standard status with BACK EXIT and CANCEL

  • buttons.

  • screen logic simply

  • PROCESS BEFORE OUTPUT.

  • MODULE STATUS_0100.

*

  • PROCESS AFTER INPUT.

  • MODULE USER_COMMAND_0100.

*

*module STATUS_0100 output.

*z_object = <zogzilla>.

  • call method z_object->display_grid

  • exporting

  • g_outtab = <dyn_table>

  • g_fldcat = it_fldcat

  • i_gridtitle = w_gridtitle

  • i_edit = w_edit

  • i_zebra = w_zebra

  • changing

  • it_fldcat = it_fldcat

  • gt_outtab = <dyn_table>.

  • set pf-status '001'.

  • set titlebar '000'.

  • ENDMODULE.

*MODULE user_command_0100 INPUT.

*

  • CASE sy-ucomm.

  • WHEN 'BACK'.

  • LEAVE PROGRAM.

  • WHEN 'EXIT'.

  • LEAVE PROGRAM.

  • WHEN 'RETURN'.

  • LEAVE PROGRAM.

  • WHEN OTHERS.

  • ENDCASE.

*ENDMODULE.

  • Function module code

  • Create instance of the ALV handling class ZCL_ALV_TEST

  • Build an FCAT based on the structure passes in my_line

  • create a dynmic table based on the FCAT created

  • call back to the calling program (invoker) to fill

  • the dynamic table

  • call the screen to display tha ALV grid

*

  • event handling etc all built into the class

if z_object is initial.

create object z_object

exporting z_object = z_object.

call method z_object->build_dynamic_structures

exporting

my_line = my_line

calling_program = invoker

importing

dy_table = dy_table

changing

it_fldcat = it_fldcat.

endif.

  • variable z_object contains the instance of our class zcl_alv_test

  • we need to keep the value as it needs to be passed to the PBO routine

  • when screen 100 is called.

assign z_object to <zogzilla>.

*

perform populate_dynamic_itab in program (invoker)

changing dy_table.

  • As detailed in the comments above this form MUST exist in the calling

  • program

*

  • change column headings etc if required - not mandatory

perform name_columns in program (invoker) if found

changing it_fldcat.

  • now display the grid

assign dy_table->* to <dyn_table>.

w_gridtitle = i_gridtitle.

w_edit = i_edit.

w_zebra = i_zebra.

call screen 100.

endfunction.

4) Update your data, delete the instance of the first call and call the FMOD again with the new structure.

You'll have to modify the fmod at one point as it makes a pefrorm populate_dynamic_itab in the calling module but it should be quite easy to generalize / parameterize the form that needs to be called to populate a new dynamic table.

Incidentally if you use this sort of approach you don't need to define a screen for each separate program for your ALV grids.

Cheers

Jimbo

29 REPLIES 29

uwe_schieferstein
Active Contributor
0 Kudos
541

Hello Edgar

The most important piece of information is missing:

<i>How and when does the user change the structure to be displayed?</i>

However, I can give you two advices:

(1) Place the call of method go_grid-><b>SET_TABLE_FOR_FIRST_DISPLAY</b> into the PBO module of your screen.

(2) When the user changes the structure (perhaps triggered by an ALV event, e.g. DOUBLE_CLICK, HOTSPOT_CLICK) you have to pass <b>PAI </b>(followed by PBO) of your screen. If required call method <b>cl_gui_cfw=>set_new_ok_code</b> in your event handler method.

For a sample report have a look at <b>ZUS_SDN_TWO_ALV_GRIDS</b> in thread

Regards,

Uwe

0 Kudos
541

Hi Uwe,

sorry for the incomplete info.....

The user changes the structure when clicking(DOUBLE_CLICK) on a tree. Then the handler method is called, where the new structure is set.

(1)The SET_TABLE_FOR_FIRST_DISPLAY method is called in the PBO module.

(2)There is no ok_code I can trigger, however the PBO is called after DOUBLE_CLICK

Any other idea?

Former Member
0 Kudos
542

I assume here you want to display a different TABLE STRUCTURE not a separate GRID.

What I do is something like this

1) define a data structure which is the table you want to display E.g

types: begin of s_elements,

tabname type dd02l-tabname,

tabclass type dd02l-tabclass,

as4user type dd02l-as4user,

as4date type dd02l-as4date,

as4time type dd02l-as4time,

viewed(1) type c.

  • drop_down_handle type int4.

types: end of s_elements.

create data dref type s_elements.

assign dref->* to <fs>.

invoker = sy-repid.

*This field symbol <fs> will contain your

  • data structure from which you construct a field catalog.

*I do it by calling methods in a class.

2) define some variables which will be needed by generating a dynamic FCAT and table

***INCLUDE ZZ_JIMBO_INCL .

  • Generic editable ALV prog with dynamic structure and FCAT.

  • Jimbo 2007.

define col_name.

read table it_fldcat into wa_it_fldcat index &1.

wa_it_fldcat-coltext = &2.

wa_it_fldcat-outputlen = &3.

modify it_fldcat from wa_it_fldcat index &1.

end-of-definition.

data: dref type ref to data,

z_object type ref to zcl_alv_test,

invoker type sy-repid,

dy_line type ref to data,

dy_table type ref to data,

it_fldcat type lvc_t_fcat,

wa_it_fldcat type lvc_s_fcat,

i_gridtitle type lvc_title,

i_zebra type lvc_edit,

i_edit type lvc_edit,

wa_elements type s_elements,

row_number type lvc_s_roid,

lt_dropdown type lvc_t_drop,

ls_dropdown type lvc_s_drop.

field-symbols: <fs> type any,

<fs1> type any,

<dyn_table> type standard table,

<dyn_wa>.

3) Call a function module which builds the dynamic fcat , dynamic table and displays the grid

create data dref type s_elements.

assign dref->* to <fs>.

invoker = sy-repid.

i_gridtitle = 'HR ESS / ITS ZHR Tables - Double click to display'.

i_zebra = ' '.

i_edit = 'X '.

  • Function module performs these subroutines in this program

  • populate_dynamic_itab

  • name_columns

*

*

  • The other subroutines are performed from within the method calls to

  • class zcl_alv_test called from our generic screen program.

call function 'ZZ_CALL_SCREEN'

exporting

invoker = invoker

my_line = <fs>

i_gridtitle = i_gridtitle

i_edit = i_edit

i_zebra = i_zebra

importing

z_object = z_object

dy_table = dy_table.

form populate_dynamic_itab changing dy_table.

data tabx like dd02l-tabname.

assign dy_table->* to <dyn_table>.

create data dy_line like line of <dyn_table>.

assign dy_line->* to <dyn_wa>.

select *

from dd02l

into corresponding fields of table <dyn_table>

where tabname like 'ZHR%'.

*drop down box values of handle

*loop at <dyn_table> into wa_elements.

  • wa_elements-drop_down_handle = '1'.

  • modify <dyn_table> from wa_elements.

  • endloop.

endform.

function zz_call_screen.

*"----


""Local interface:

*" IMPORTING

*" REFERENCE(INVOKER) TYPE SYREPID

*" REFERENCE(MY_LINE) TYPE ANY

*" REFERENCE(I_GRIDTITLE) TYPE LVC_TITLE

*" REFERENCE(I_EDIT) TYPE LVC_EDIT

*" REFERENCE(I_ZEBRA) TYPE LVC_EDIT

*" EXPORTING

*" REFERENCE(DY_TABLE) TYPE REF TO DATA

*" REFERENCE(Z_OBJECT) TYPE REF TO ZCL_ALV_TEST

*"----


*

  • This function module instantiates a generic

  • ALV handling class

  • Builds a dynamic fcat from the structure passed in my_line

  • Creates a dynmic table using the FCAT created in the class

  • calls the alv display

  • Using this approach means that the calling programs

  • now no longer need a separate screen.

  • The dynamic table is now filled in the

  • form POPULATE_DYNAMIC_TABLE

  • which MUST exist in the calling program.

  • It is done this way as it is not praticable to have

  • a completely generic method of filling the dynamic table

  • as data selection depends on the application - could be via

  • joins etc etc.

  • Note that screen 100 and a standard interface (se41) are contained in

  • the main program of this function module.

  • screen just has one element a custom container called CCONTAINER1

  • status (SE41) is just a standard status with BACK EXIT and CANCEL

  • buttons.

  • screen logic simply

  • PROCESS BEFORE OUTPUT.

  • MODULE STATUS_0100.

*

  • PROCESS AFTER INPUT.

  • MODULE USER_COMMAND_0100.

*

*module STATUS_0100 output.

*z_object = <zogzilla>.

  • call method z_object->display_grid

  • exporting

  • g_outtab = <dyn_table>

  • g_fldcat = it_fldcat

  • i_gridtitle = w_gridtitle

  • i_edit = w_edit

  • i_zebra = w_zebra

  • changing

  • it_fldcat = it_fldcat

  • gt_outtab = <dyn_table>.

  • set pf-status '001'.

  • set titlebar '000'.

  • ENDMODULE.

*MODULE user_command_0100 INPUT.

*

  • CASE sy-ucomm.

  • WHEN 'BACK'.

  • LEAVE PROGRAM.

  • WHEN 'EXIT'.

  • LEAVE PROGRAM.

  • WHEN 'RETURN'.

  • LEAVE PROGRAM.

  • WHEN OTHERS.

  • ENDCASE.

*ENDMODULE.

  • Function module code

  • Create instance of the ALV handling class ZCL_ALV_TEST

  • Build an FCAT based on the structure passes in my_line

  • create a dynmic table based on the FCAT created

  • call back to the calling program (invoker) to fill

  • the dynamic table

  • call the screen to display tha ALV grid

*

  • event handling etc all built into the class

if z_object is initial.

create object z_object

exporting z_object = z_object.

call method z_object->build_dynamic_structures

exporting

my_line = my_line

calling_program = invoker

importing

dy_table = dy_table

changing

it_fldcat = it_fldcat.

endif.

  • variable z_object contains the instance of our class zcl_alv_test

  • we need to keep the value as it needs to be passed to the PBO routine

  • when screen 100 is called.

assign z_object to <zogzilla>.

*

perform populate_dynamic_itab in program (invoker)

changing dy_table.

  • As detailed in the comments above this form MUST exist in the calling

  • program

*

  • change column headings etc if required - not mandatory

perform name_columns in program (invoker) if found

changing it_fldcat.

  • now display the grid

assign dy_table->* to <dyn_table>.

w_gridtitle = i_gridtitle.

w_edit = i_edit.

w_zebra = i_zebra.

call screen 100.

endfunction.

4) Update your data, delete the instance of the first call and call the FMOD again with the new structure.

You'll have to modify the fmod at one point as it makes a pefrorm populate_dynamic_itab in the calling module but it should be quite easy to generalize / parameterize the form that needs to be called to populate a new dynamic table.

Incidentally if you use this sort of approach you don't need to define a screen for each separate program for your ALV grids.

Cheers

Jimbo

0 Kudos
541

Hi Jimbo,

I also used only one grid for all different structures. This works fine.

But I also want to use the ALV standard functionality where the user can save layouts.

If you allow this using only one grid doesn't work because the saved default layout is not correct when you are changing the structure. So I thought that if you are creating a ALV instance for every structure the saved default layout would be correct.

Best Regards, Edgar

0 Kudos
541

Hi Edgar,

I had the same problem.

I wrote an application which displays different ALVs in the same container placed on a subscreen which is called by 6 different subscreens in a TabStrip Control...I was going crazy.

I have:

SCREEN 200 -> Call a TabStrip Control with 6 strips (so, 6 subscreens) ->every strip calls Subscreen 9999 -> create a control to attach an ALV.

Based on the clicked Strip I was assigning a Field-Symbol and changing the instance of the current ALV with the new structure.

Everything worked fine in debugger, but I wasn't able to see changes on the screen. It always displayed the first table, even in other strips.

The issue was with the container. In the PBO module of every strip, now I free the container that is re-created in the PBO of screen 9999.

The only bad thing is that you see a flashing window (for less than a second) during the refresh of the container, but everything works fine.

Maybe this is not an elegant way (so I am interested too in a new solution), but it works...

Hope this helps,

Roby.

PS: Anyway, I'm using the SALV Model, not cl_gui_alv_grid..

0 Kudos
541

Hi Edgar,

I had the same problem.

I wrote an application which displays different ALVs in the same container placed on a subscreen which is called by 6 different subscreens in a TabStrip Control...I was going crazy.

I have:

SCREEN 200 -> Call a TabStrip Control with 6 strips (so, 6 subscreens) ->every strip calls Subscreen 9999 -> create a control to attach an ALV.

Based on the clicked Strip I was assigning a Field-Symbol and changing the instance of the current ALV with the new structure.

Everything worked fine in debugger, but I wasn't able to see changes on the screen. It always displayed the first table, even in other strips.

The issue was with the container. In the PBO module of every strip, now I free the container that is re-created in the PBO of screen 9999.

The only bad thing is that you see a flashing window (for less than a second) during the refresh of the container, but everything works fine.

Maybe this is not an elegant way (so I am interested too in a new solution), but it works...

Hope this helps,

Roby.

0 Kudos
541

Hi Roby,

nice solution and congratulations, but in my case I could have more than 6 tabstrips. Furthermore using my tree with only one ALV is easy to handle.

By the way, I also tried to free the container before calling another structure. The result is an empty container.

You mentioned, that you used an subscreen and it works. Perhaps this would be a alternative, instead of using an splitter container. But I don't like the subscreen in my application because you can't change the size.

Thanks and Best Regards, Edgar

0 Kudos
541

Hi Robert

The problem with cl_salv* classes is that there is no EDIT functionality in them. This might not be a problem for your application but could be for other related stuff.

As for the saving the layout's I haven't tried that yet but in theory if you also change the layout dynamically as well as your FCAT for the new grid it should in theory work. (In theory as far as SAP is concerned doesn't always work as expected !!).

The relevant structure is alv_s_layo. Change this when modifying the field catalog for your new structure.

The other point to remember here is you'll need to have set up the correct layout before you can reload the layout or you'll get some type of problem for sure.

I'll have a go with this later.

Incidentally again using the cl_gui_alv type of classes or basing user derived one's on this it is possible in the case of displaying a single grid to be able to use a Single screen via a function module call as displayed above.

If you have say 30 relatively similar reports using a grid you don't really want to have 3à identical screens --one for each program.

My next step also is to make the whole thing completely active either via a Portal / HTML/XML script or a SAP front end transaction where the user can build a dynamic query. For anybody who'se used it SAP ABAP Query is an abomination.

Cheers

Jimbo

0 Kudos
541

If I understood well, you have a vertical splitter container.

On the left you have a tree with different tables (different structures) and on double click you need to display them on the right in an ALV Grid.

Is this correct?

Maybe this local class can help you. This was the old output of the report I've explained before.

It works exactly as you mean, tree on the left with different nodes. Every node is a table (in fact, a table from B2 Cluster). On double click, the contents of the selected table is displayed on the right grid.

Check this out (sorry, it's a bit long):


*----------------------------------------------------------------------*
*       CLASS lcl_screen_handler DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_screen_handler DEFINITION CREATE PRIVATE.

  PUBLIC SECTION.

    CLASS-DATA:     tree_agent    TYPE REF TO lcl_screen_handler.
    CLASS-METHODS:  create_screen.

    METHODS: constructor IMPORTING im_pernrs TYPE ty_pernr_tab.

  PRIVATE SECTION.

* // Screen Elements:
    DATA: container_screen   TYPE REF TO cl_gui_custom_container,
          splitter_container TYPE REF TO cl_gui_easy_splitter_container,
          container_tree     TYPE REF TO cl_gui_container,
          container_grid     TYPE REF TO cl_gui_container,
          tree               TYPE REF TO cl_simple_tree_model,
          grid               TYPE REF TO cl_gui_alv_grid.

    DATA: a_employees TYPE ty_pernr_tab,
          a_layo      TYPE lvc_s_layo,
          a_fcat      TYPE lvc_t_fcat.

    METHODS: create_gui_controls,
             fill_tree,
             set_pernrs  IMPORTING im_pernrs          TYPE ty_pernr_tab,
             set_layout,
             set_fieldcat IMPORTING im_table          TYPE table,
             get_label    IMPORTING im_name           TYPE abap_compdescr-name
                          RETURNING value(ex_label)   TYPE lvc_s_fcat-scrtext_m,

             handle_node_double_click FOR EVENT node_double_click
                                      OF cl_simple_tree_model
                                      IMPORTING node_key.

ENDCLASS.                    "lcl_screen_handler DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_screen_handler IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_screen_handler IMPLEMENTATION.

  METHOD create_screen.

    IF tree_agent IS INITIAL.
      CREATE OBJECT tree_agent EXPORTING im_pernrs = pernr_tab[].
    ENDIF.

  ENDMETHOD.                    "create_screen

  METHOD constructor.

    me->set_pernrs( im_pernrs ).
    me->create_gui_controls( ).
    me->fill_tree( ).

  ENDMETHOD.                    "constructor

  METHOD create_gui_controls.

    DATA: lt_tree_events TYPE cntl_simple_events,
          ls_tree_event  TYPE cntl_simple_event.

    CREATE OBJECT container_screen   EXPORTING container_name = 'CUSTOM_CONTROL'.
    CREATE OBJECT splitter_container EXPORTING parent         = container_screen
                                               orientation    = cl_gui_easy_splitter_container=>orientation_horizontal
                                               sash_position  = 35.
* // Left region: Tree
    container_tree = splitter_container->top_left_container.
* // Right region: Grid
    container_grid = splitter_container->bottom_right_container.
* // Tree Control
    CREATE OBJECT tree EXPORTING node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single.
    tree->create_tree_control( container_tree ).
    ls_tree_event-eventid = cl_simple_tree_model=>eventid_node_double_click.
    ls_tree_event-appl_event = ' '.
    APPEND ls_tree_event TO lt_tree_events.
    tree->set_registered_events( EXPORTING events = lt_tree_events ).
    SET HANDLER me->handle_node_double_click FOR tree.
* // Grid Control
    CREATE OBJECT grid EXPORTING i_parent = container_grid.

  ENDMETHOD.                    "create_gui_controls

  METHOD fill_tree.

    DATA: lt_node_table TYPE treemsnota,
          ls_node_line  TYPE treemsnodt.
    DATA: a_employee    TYPE ty_pernr,
          last_pernr    TYPE pernr_d.

* // Set Root Node:
    ls_node_line-node_key = 'ROOT'.
    ls_node_line-isfolder = 'X'.
    ls_node_line-text     = 'Lista C.I.D elaborati'.
    icon_create 'ICON_WD_TREE' ls_node_line-n_image.
*    ls_node_line-n_image  = 'ICON_WD_TREE'.
    APPEND ls_node_line TO lt_node_table. CLEAR ls_node_line.

* // Append pernrs:
    LOOP AT a_employees INTO a_employee.
      IF a_employee-pernr NE last_pernr.
        last_pernr = a_employee-pernr.
        ls_node_line-node_key  = a_employee-pernr.
        ls_node_line-relatkey  = 'ROOT'.
        ls_node_line-relatship = cl_tree_model=>relat_last_child.
        icon_create 'ICON_POSITION_HR' ls_node_line-n_image.
        CONCATENATE a_employee-pernr a_employee-ename INTO ls_node_line-text
          SEPARATED BY ' - '.
        APPEND ls_node_line TO lt_node_table. CLEAR ls_node_line.
* // Infotype 2006:
        CONCATENATE a_employee-pernr 'P2' INTO ls_node_line-node_key.
        ls_node_line-relatkey   = a_employee-pernr.
        ls_node_line-relatship  = cl_tree_model=>relat_last_child.
        READ TABLE p2006_differences WITH KEY pernr = a_employee-pernr
             TRANSPORTING NO FIELDS.
        IF sy-subrc EQ 0.
          icon_create 'ICON_TREND_UNCHANGED' ls_node_line-n_image.
          ls_node_line-text       = 'Differenze in Infotype 2006'.
        ELSE.
          icon_create 'ICON_LED_GREEN' ls_node_line-n_image.
          ls_node_line-text       = 'Non esistono differenze in IT 2006'.
        ENDIF.
        APPEND ls_node_line TO lt_node_table.
* // Differenze ZES
        CONCATENATE a_employee-pernr 'ZE' INTO ls_node_line-node_key.
        READ TABLE zes_differences WITH KEY pernr = a_employee-pernr
             TRANSPORTING NO FIELDS.
        IF sy-subrc EQ 0.
          icon_create 'ICON_TREND_UNCHANGED' ls_node_line-n_image.
          ls_node_line-text       = 'Differenze Tabella ZES'.
        ELSE.
          icon_create 'ICON_LED_GREEN' ls_node_line-n_image.
          ls_node_line-text       = 'Non esistono differenze in Tab. ZES'.
        ENDIF.
        APPEND ls_node_line TO lt_node_table.
* // Differenze ZL
        CONCATENATE a_employee-pernr 'ZL' INTO ls_node_line-node_key.
        READ TABLE zl_differences WITH KEY pernr = a_employee-pernr
             TRANSPORTING NO FIELDS.
        IF sy-subrc EQ 0.
          icon_create 'ICON_TREND_UNCHANGED' ls_node_line-n_image.
          ls_node_line-text       = 'Differenze in Tabella ZL'.
        ELSE.
          icon_create 'ICON_LED_GREEN' ls_node_line-n_image.
          ls_node_line-text       = 'Non esistono differenze in Tab. ZL'.
        ENDIF.
        APPEND ls_node_line TO lt_node_table.
* // Differenze SALDO
        CONCATENATE a_employee-pernr 'SL' INTO ls_node_line-node_key.
        READ TABLE saldo_differences WITH KEY pernr = a_employee-pernr
             TRANSPORTING NO FIELDS.
        IF sy-subrc EQ 0.
          icon_create 'ICON_TREND_UNCHANGED' ls_node_line-n_image.
          ls_node_line-text       = 'Differenze Tabella SALDO'.
        ELSE.
          icon_create 'ICON_LED_GREEN' ls_node_line-n_image.
          ls_node_line-text       = 'Non esistono differenze in Tab. SALDO'.
        ENDIF.
        APPEND ls_node_line TO lt_node_table.
* // Differenze ABWKONTI
        CONCATENATE a_employee-pernr 'AB' INTO ls_node_line-node_key.
        READ TABLE abwkonti_differences WITH KEY pernr = a_employee-pernr
             TRANSPORTING NO FIELDS.
        IF sy-subrc EQ 0.
          icon_create 'ICON_TREND_UNCHANGED' ls_node_line-n_image.
          ls_node_line-text       = 'Differenze in Tabella ABWKONTI'.
        ELSE.
          icon_create 'ICON_LED_GREEN' ls_node_line-n_image.
          ls_node_line-text       = 'Non esistono differenze in Tab. ABWKONTI'.
        ENDIF.
        APPEND ls_node_line TO lt_node_table.
* // Differenze QTACC
        CONCATENATE a_employee-pernr 'QT' INTO ls_node_line-node_key.
        READ TABLE qtacc_differences WITH KEY pernr = a_employee-pernr
             TRANSPORTING NO FIELDS.
        IF sy-subrc EQ 0.
          icon_create 'ICON_TREND_UNCHANGED' ls_node_line-n_image.
          ls_node_line-text       = 'Differenze in Tabella QTACC'.
        ELSE.
          icon_create 'ICON_LED_GREEN' ls_node_line-n_image.
          ls_node_line-text       = 'Non esistono differenze in Tab. QTACC'.
        ENDIF.
        APPEND ls_node_line TO lt_node_table.
* // Differenze QTACC
        CONCATENATE a_employee-pernr 'ZK' INTO ls_node_line-node_key.
        READ TABLE zko_differences WITH KEY pernr = a_employee-pernr
             TRANSPORTING NO FIELDS.
        IF sy-subrc EQ 0.
          icon_create 'ICON_TREND_UNCHANGED' ls_node_line-n_image.
          ls_node_line-text       = 'Differenze in Tabella ZKO'.
        ELSE.
          icon_create 'ICON_LED_GREEN' ls_node_line-n_image.
          ls_node_line-text       = 'Non esistono differenze in Tab. ZKO'.
        ENDIF.
        APPEND ls_node_line TO lt_node_table.
      ENDIF.
    ENDLOOP.

* // Add Nodes to tree control:
    tree->add_nodes( EXPORTING node_table = lt_node_table ).
    tree->expand_root_nodes( ).
* // Send message if there are messages
    IF LINES( message_tab ) GT 0.
      ss_msg = text-m00.
      MESSAGE ss_msg TYPE 'S'.
    ENDIF.

  ENDMETHOD.                    "fill_tree

  METHOD set_pernrs.

    a_employees[] = im_pernrs[].

  ENDMETHOD.                    "set_pernrs

  METHOD handle_node_double_click.

    FIELD-SYMBOLS: <table> TYPE table,
                   <line>  TYPE ANY,
                   <field> TYPE ANY.

    DATA: table         TYPE c LENGTH 2,
          table_object  TYPE REF TO data.

    CHECK node_key NE 'ROOT' AND node_key IS NOT INITIAL.

    table = node_key+8(2).

    CASE table.
      WHEN 'P2'.    "Differenze 2006
        CREATE DATA table_object LIKE TABLE OF p2006_differences.
        ASSIGN table_object->* TO <table>.
        <table>[] = p2006_differences[].
      WHEN 'ZE'.
        CREATE DATA table_object LIKE TABLE OF zes_differences.
        ASSIGN table_object->* TO <table>.
        <table>[] = zes_differences[].
      WHEN 'ZL'.
        CREATE DATA table_object LIKE TABLE OF zl_differences.
        ASSIGN table_object->* TO <table>.
        <table>[] = zl_differences[].
      WHEN 'SL'.
        CREATE DATA table_object LIKE TABLE OF saldo_differences.
        ASSIGN table_object->* TO <table>.
        <table>[] = saldo_differences[].
      WHEN 'AB'.
        CREATE DATA table_object LIKE TABLE OF abwkonti_differences.
        ASSIGN table_object->* TO <table>.
        <table>[] = abwkonti_differences[].
      WHEN 'QT'.
        CREATE DATA table_object LIKE TABLE OF qtacc_differences.
        ASSIGN table_object->* TO <table>.
        <table>[] = qtacc_differences[].
      WHEN 'ZK'.
        CREATE DATA table_object LIKE TABLE OF zko_differences.
        ASSIGN table_object->* TO <table>.
        <table>[] = zko_differences[].
      WHEN OTHERS.
        RETURN.
    ENDCASE.

* // Filter.
    LOOP AT <table> ASSIGNING <line>.
      ASSIGN COMPONENT 'PERNR' OF STRUCTURE <line> TO <field>.
      IF <field> NE node_key(8).
        DELETE TABLE <table> FROM <line>.
      ENDIF.
    ENDLOOP.

    me->set_layout( ).
    me->set_fieldcat( EXPORTING im_table = <table> ).
    grid->set_table_for_first_display( EXPORTING is_layout       = a_layo
                                       CHANGING  it_outtab       = <table>[]
                                                 it_fieldcatalog = a_fcat ).

  ENDMETHOD.                    "handle_node_double_click

  METHOD set_layout.

    a_layo-zebra = abap_true.
    a_layo-cwidth_opt = abap_true.

  ENDMETHOD.                    "set_layout

  METHOD set_fieldcat.

    DATA: ls_fcat     TYPE lvc_s_fcat,
          struc_ref   TYPE REF TO cl_abap_structdescr,
          component   TYPE abap_compdescr,
          lv_tabname  TYPE lvc_s_fcat-tabname.
    DATA: data_object TYPE REF TO data.
    FIELD-SYMBOLS: <line>       TYPE ANY.
    DATA: label       TYPE lvc_s_fcat-scrtext_m.

    REFRESH a_fcat.

    CREATE DATA data_object LIKE LINE OF im_table.
    ASSIGN data_object->* TO <line>.

    struc_ref ?= cl_abap_structdescr=>describe_by_data( <line> ).
    IF struc_ref IS BOUND.
      LOOP AT struc_ref->components INTO component.
        ls_fcat-fieldname = component-name.
        ls_fcat-tabname = lv_tabname.
        IF component-name EQ 'PERNR' OR component-name EQ 'ENAME'.
*          ls_fcat-key = abap_true.
          ls_fcat-emphasize = 'C410'.
          IF component-name EQ 'PERNR'.
            ls_fcat-scrtext_m = me->get_label( 'PERNR_D' ).
          ELSEIF component-name EQ 'ENAME'.
            ls_fcat-scrtext_m = me->get_label( 'EMNAM' ).
          ENDIF.
        ELSE.
          ls_fcat-scrtext_m = me->get_label( component-name ).
        ENDIF.
        IF component-name EQ 'DIFFERENT'.
          ls_fcat-icon      = abap_true.
          ls_fcat-scrtext_m = 'Tipo Differenza'.
        ENDIF.
* // Local / Remote section:
        IF ls_fcat-fieldname(3) EQ 'LCL'.
          CONCATENATE ls_fcat-scrtext_m '(Loc.)' INTO label SEPARATED BY space.
          IF sy-subrc NE 0.
            ls_fcat-scrtext_l = ls_fcat-scrtext_m. CLEAR ls_fcat-scrtext_m.
            CONCATENATE ls_fcat-scrtext_l '(Loc.)' INTO ls_fcat-scrtext_l
                        SEPARATED BY space.
          ELSE.
            ls_fcat-scrtext_m = label.
            CLEAR label.
          ENDIF.
          ls_fcat-emphasize = 'C300'.
        ELSEIF ls_fcat-fieldname(3) EQ 'REM'.
          CONCATENATE ls_fcat-scrtext_m '(Rem.)' INTO label SEPARATED BY space.
          IF sy-subrc NE 0.
            ls_fcat-scrtext_l = ls_fcat-scrtext_m. CLEAR ls_fcat-scrtext_m.
            CONCATENATE ls_fcat-scrtext_l '(Rem.)' INTO ls_fcat-scrtext_l
                        SEPARATED BY space.
          ELSE.
            ls_fcat-scrtext_m = label.
            CLEAR label.
          ENDIF.
          ls_fcat-emphasize = 'C600'.
        ENDIF.
* // End
        APPEND ls_fcat TO a_fcat. CLEAR ls_fcat.
      ENDLOOP.
    ENDIF.

  ENDMETHOD.                    "set_fieldcat

  METHOD get_label.

    DATA: ls_dfies    TYPE dfies,
          elem_ref    TYPE REF TO cl_abap_elemdescr,
          type_ref    TYPE REF TO cl_abap_typedescr.
    DATA: lcl_name    TYPE abap_compdescr-name,
          offset      TYPE i,
          length      TYPE i.

* // Get Elem. Description
    CALL METHOD cl_abap_elemdescr=>describe_by_name( EXPORTING  p_name          = im_name
                                                     RECEIVING  p_descr_ref     = type_ref
                                                     EXCEPTIONS type_not_found  = 20 ).
* // Old Exception treatment:
    IF sy-subrc EQ 0.
* // Cast down to Element Descr from Type Descr
      TRY.
          elem_ref ?= type_ref.
        CATCH cx_sy_move_cast_error.
          ex_label = im_name. RETURN.
      ENDTRY.
* // If it exists in dictionary, get label:
      IF elem_ref->is_ddic_type( ) EQ abap_true.
        ls_dfies = elem_ref->get_ddic_field( ).
        ex_label = ls_dfies-scrtext_m.
      ENDIF.
    ELSE.
* // Otherwise:
      CASE im_name(3).
* // Clear the Local/Remote Indicator from field:
        WHEN 'LCL' OR 'REM'.
          offset = 4.
          length = STRLEN( im_name ) - 4.
          lcl_name = im_name+offset(length).
* // Call myself and I
          ex_label = me->get_label( lcl_name ).
* // PT/PTM specific elements are pretty different
          IF ex_label IS INITIAL OR ex_label EQ lcl_name.
            CASE lcl_name.
              WHEN 'DESTA'.
                lcl_name = 'PTM_DEDSTART'.
                ex_label = me->get_label( lcl_name ).
              WHEN 'DEEND'.
                lcl_name = 'PTM_DEDEND'.
                ex_label = me->get_label( lcl_name ).
              WHEN 'ZTART'.
                lcl_name = 'PT_ZTART'.
                ex_label = me->get_label( lcl_name ).
              WHEN 'ACCAC'.
                lcl_name = 'PTM_CURGEN'.
                ex_label = me->get_label( lcl_name ).
              WHEN 'ACCCU'.
                lcl_name = 'PTM_CURCUM'.
                ex_label = me->get_label( lcl_name ).
              WHEN OTHERS.
                ex_label = im_name.
            ENDCASE.
          ENDIF.
        WHEN OTHERS.
          ex_label = im_name.
      ENDCASE.
    ENDIF.
* // End for labels
  ENDMETHOD.                    "get_label

ENDCLASS.                    "lcl_screen_handler IMPLEMENTATION

*&---------------------------------------------------------------------*
*&      Module  STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
MODULE status_0100 OUTPUT.

* // Inserire PF-Status
  SET PF-STATUS 'MAIN_100'.
  SET TITLEBAR '100'.
  lcl_screen_handler=>create_screen( ).

ENDMODULE.                 " STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  exit  INPUT
*&---------------------------------------------------------------------*
MODULE exit INPUT.

  SET SCREEN 0.
  LEAVE SCREEN.

ENDMODULE.                 " exit  INPUT

*---------------------------------------------------------------------*
*  MODULE user_command_0100
*---------------------------------------------------------------------*
MODULE user_command_0100.

  PERFORM user_command.

ENDMODULE.                    "user_command_0100

Hope this helps,

Roby.

0 Kudos
541

The problem here are these statements

CASE table.

WHEN 'P2'. "Differenze 2006

CREATE DATA table_object LIKE TABLE OF p2006_differences.

ASSIGN table_object->* TO <table>.

<table>\[] = p2006_differences[].

WHEN 'ZE'.

CREATE DATA table_object LIKE TABLE OF zes_differences.

ASSIGN table_object->* TO <table>.

<table>\[] = zes_differences[].

WHEN 'ZL'.

CREATE DATA table_object LIKE TABLE OF zl_differences.

ASSIGN table_object->* TO <table>.

<table>\[] = zl_differences[].

WHEN 'SL'. --- etc etc

My understanding that these should be entirely dynamic so the different table layout structures aren't embedded in the same mainline program code.

so you need something like create <dyn_table1> then display

then depending on user interaction create <dyn_table2> and display.

The case in your code isn't what I understand as being really 'Dynamic' although a good example for what it does.

Your table structures should be input parametrically and then built.

I still also like the idea of trying to have the screen handler and grid calling part in a separate function module to avoid the single screen required for each program.

I haven't tried using the splitter method yet as most apps I've needed so far have been essentially full screen apps but will give this a go later as I'm sure it will work.

Cheers

jimbo

0 Kudos
541

Hi Roby,

yes you are right......

Because this is a really huger example I need some time to check it.

Thank you and best regards, Edgar

0 Kudos
541

Hi Roby,

I have checked your example. As I understand you have the same output than your example before, what means the tree and the alv is nested in a subscreen. This subscreen is displayed in a tab strib control, right?

I tried your example using also a subscreen where I embedded the splitter conatiner. Unfortunately I have the same effect, the alv data was not upated.

Best Regards and thank you, Edgar

0 Kudos
541

Hi there

This method works (haven't got round to dynamic layout set saving and loading yet).

For example this program displays a list of tables.

When a table is double clicked the relevant table is displayed in a new grid.

On exit the cusor is moved to the name of the table that was viewed (selected) and a field updated with a V to indicate Viewed.

The Double click handler calls a form in the invoking program --you can see from the code it's not too long.

PROGRAM zzjimbozzz.

  • Generic editable ALV prog with dynamic structure and FCAT.

  • Jimbo 2007.

TABLES : dd02l.

TYPES: BEGIN OF s_elements,

tabname TYPE dd02l-tabname,

tabclass TYPE dd02l-tabclass,

as4user TYPE dd02l-as4user,

as4date TYPE dd02l-as4date,

as4time TYPE dd02l-as4time,

viewed(1) TYPE c.

  • drop_down_handle type int4.

TYPES: END OF s_elements.

DATA: tabname LIKE dd02l-tabname.

PARAMETERS: p_struct TYPE dd02l-tabname.

INCLUDE zz_jimbo_incl.

IF p_struct IS INITIAL.

CREATE DATA dref TYPE s_elements.

ASSIGN dref->* TO <fs>.

i_routine = 'POPULATE_DYNAMIC_ITAB'.

i_names = 'NAME_COLUMNS'.

i_gridtitle = 'HR ESS / ITS ZHR Tables - Double click to display'.

ELSE.

tabname = p_struct.

CREATE DATA dref TYPE (tabname).

ASSIGN dref->* TO <fs>.

i_routine = 'POPULATE_DYNAMIC_ITAB2'.

i_gridtitle = 'Generalized table display '.

ENDIF.

invoker = sy-repid.

i_zebra = ' '.

i_edit = 'X '.

  • Function module performs these subroutines in this program

  • populate_dynamic_itab

  • name_columns

*

*

  • The other subroutines are performed from within the method calls to

  • class zcl_alv_test called from our generic screen program.

CALL FUNCTION 'ZZ_CALL_SCREEN'

EXPORTING

invoker = invoker

my_line = <fs>

i_gridtitle = i_gridtitle

i_edit = i_edit

i_zebra = i_zebra

i_names = i_names

i_routine = i_routine

IMPORTING

z_object = z_object

dy_table = dy_table.

FORM populate_dynamic_itab CHANGING dy_table.

ASSIGN dy_table->* TO <dyn_table>.

CREATE DATA dy_line LIKE LINE OF <dyn_table>.

ASSIGN dy_line->* TO <dyn_wa>.

SELECT *

FROM dd02l

INTO CORRESPONDING FIELDS OF TABLE <dyn_table>

WHERE tabname LIKE 'ZHR%'.

*drop down box values of handle

*loop at <dyn_table> into wa_elements.

  • wa_elements-drop_down_handle = '1'.

  • modify <dyn_table> from wa_elements.

  • endloop.

ENDFORM.

FORM name_columns CHANGING it_fldcat TYPE lvc_t_fcat.

  • Here before displaying you can change the field catalog to

  • adjust your own column names.

*col_name col-nr 'your name' output length.

col_name 1 'Table name' 30.

col_name 2 'Table class' 12.

col_name 3 'Changed By' 12.

col_name 4 ' On' 12.

col_name 5 ' At' 8.

col_name 6 'Act' 3.

  • Make any other changes to the field catalog

  • for example colour cells or drop down box

ENDFORM.

FORM dubbelklik

USING

e_row TYPE lvc_s_row

e_column TYPE lvc_s_col

es_row_no TYPE lvc_s_roid.

READ TABLE <dyn_table> INDEX e_row INTO wa_elements.

tabname = wa_elements-tabname.

if p_struct is initial.

SUBMIT zzjimbozzz

WITH p_struct = tabname

AND RETURN.

clear p_struct.

endif.

wa_elements-viewed = 'V'.

MODIFY <dyn_table> FROM wa_elements INDEX e_row.

PERFORM refresh.

row_number-row_id = e_row.

CALL METHOD z_object->set_cell

EXPORTING

e_column = e_column

es_row_no = row_number.

ENDFORM.

FORM data_changed

USING

changed_tab

inserted_tab

deleted_tab

modified_cells_tab.

ASSIGN changed_tab->* TO <fs1>.

  • code anything here to be done when data in the grid is changed.

ENDFORM.

FORM populate_dynamic_itab2 CHANGING dy_table.

CREATE DATA dref TYPE (tabname).

ASSIGN dy_table->* TO <dyn_table>.

CREATE DATA dy_line LIKE LINE OF <dyn_table>.

ASSIGN dy_line->* TO <dyn_wa>.

SELECT *

FROM (tabname)

INTO CORRESPONDING FIELDS OF TABLE <dyn_table>.

ENDFORM.

FORM data_changed_finished.

IF <fs1> IS ASSIGNED.

  • code for any processing needed at end of data change

  • updated data is in <dyn_table>.

  • if <fs1> not assigned then no data has been changed.

UNASSIGN <fs1>.

ENDIF.

ENDFORM.

FORM process.

  • ALV GRID changed table is in <dyn_table>.

LOOP AT <dyn_table> INTO <dyn_wa>.

  • Do what you want

  • end

ENDLOOP.

ENDFORM.

FORM refresh.

CALL METHOD z_object->refresh_grid.

ENDFORM.

The include just has field symbols etc in it

***INCLUDE ZZ_JIMBO_INCL .

  • Generic editable ALV prog with dynamic structure and FCAT.

  • Jimbo 2007.

DEFINE col_name.

read table it_fldcat into wa_it_fldcat index &1.

wa_it_fldcat-coltext = &2.

wa_it_fldcat-outputlen = &3.

modify it_fldcat from wa_it_fldcat index &1.

END-OF-DEFINITION.

DATA: dref TYPE REF TO data,

z_object TYPE REF TO zcl_alv_test, "My ALV class

invoker TYPE sy-repid,

dy_line TYPE REF TO data,

dy_table TYPE REF TO data,

it_fldcat TYPE lvc_t_fcat,

wa_it_fldcat TYPE lvc_s_fcat,

i_gridtitle TYPE lvc_title,

i_zebra TYPE lvc_edit,

i_edit TYPE lvc_edit,

wa_elements TYPE s_elements,

row_number TYPE lvc_s_roid,

i_routine(30) TYPE c,

i_names(30) TYPE c,

lt_dropdown TYPE lvc_t_drop,

ls_dropdown TYPE lvc_s_drop.

FIELD-SYMBOLS: <fs> TYPE ANY,

<fs1> TYPE ANY,

<dyn_table> TYPE STANDARD TABLE,

<dyn_wa>.

The relevant methods in the class

method on_dubbelklik.

call method me->dubbelklik

exporting

e_row = e_row

e_column = e_column

es_row_no = es_row_no.

  • ...

endmethod.

method dubbelklik.

perform dubbelklik in program (caller) if found

using

e_row

e_column

es_row_no.

  • ...

endmethod.

The trick is just to resubmit the program with return and pass the new structure to your program.

You still only need one screen as it's all handled in the function module call function 'ZZ_CALL_SCREEN'

On exit you are back into your original code where you can then proceed with your updates.

You can extend the usefulness of this in a number of ways but simple examples are best for starting with.

Cheers

Jimbo

0 Kudos
541

Hi Jimbo,

nice trick but not suitable for my application.

In my layout I have one simple tree on the left side of the screen and one alv tree for displaying the tree data on the right side of the screen. The display structure changes for every hierachy level of the tree. The tree hierarchy can be always diffrent for every call of the program. The controls are embedded in a splitter container, because the size of the tree/alv screen should be changed by the user. Additionally I want that the screen layouts of the ALV can be saved by the user.

Considering those requirements I can't use your example.

Best regards and thank you

Edgar

0 Kudos
541

Hi Edgar,

my second example is not working with subscreens. I have only one dynpro call, the main output screen 200.

In this screen I've create a custom control. And this CC is splitted by using a dynamic splitter container.

Then, container1 is used by the left tree and container2 is used by right grid.

It's something strange...as you see in this report I don't free the container any time I call a new grid, but I ensure you that data is refreshed..

0 Kudos
541

Hi Edgar,

I just finished writing a program accordingly to your specifications. I don't know if it's exactly what you need, but at least the output management is just like you have explained:

This report has a little selection-screen, where you can delimit the selection of the tables by username (DD02L-AS4USER) or directly by the tablename.

The tree will show a hierarchy like this:

ROOT

-


> USER

-


>TABLENAME

Double-Clicking the tablename, you will see contents in the right grid.

Please note that, having only DDIC tables, I've not inserted a fieldcatalog generation.

The display process is all handled by a local class SCREEN_HANDLER.

Here is the code from MAIN:


*&---------------------------------------------------------------------*
*& Report  ZBC_SDN_TREE_AND_ALV
*&
*&---------------------------------------------------------------------*
*&  Description: Show a screen, splitted by a container, in which the
*&               left region it's a tree containing a DB-Table hierarchy
*&               and the right region shows the contents of the selected
*&               table
*&  SDN Thread:  Dynamic Call of ALV - No data update
*&               <a class="jive_macro jive_macro_thread" href="" __jive_macro_name="thread" modifiedtitle="true" __default_attr="671248"></a>
*&---------------------------------------------------------------------*

REPORT  zbc_sdn_tree_and_alv.

TABLES: dd02l.
TYPE-POOLS: abap.

* // Table containing the nodes of the left tree
TYPES: BEGIN OF left_region,
        as4user  TYPE dd02l-as4user,
        tabname  TYPE dd02l-tabname,
       END OF left_region.
TYPES: left_table TYPE STANDARD TABLE OF left_region.
DATA:  tree_table TYPE left_table,
       tree_line  TYPE left_region.

* // Rigth region is fully dynamic, so no data structure:
* // Screen Handler:
INCLUDE zbc_sdn_tree_and_alv_c01.

* // Small Selscreen.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001. "Selection Options
SELECT-OPTIONS: s_user  FOR dd02l-as4user,
                s_table FOR dd02l-tabname MATCHCODE OBJECT dd_tabl.
SELECTION-SCREEN END OF BLOCK b1.

START-OF-SELECTION.

* // Get tables based on selscreen parameters:
  SELECT as4user tabname INTO CORRESPONDING FIELDS OF TABLE tree_table
                         FROM  dd02l
                         WHERE tabname  IN s_table
                         AND   as4local EQ 'A' "Active Object
                         AND   as4user  IN s_user
                         AND   tabclass EQ 'TRANSP'.
  IF sy-subrc NE 0.
    MESSAGE 'No tables for the choosen parameters'(002) TYPE 'E'.
  ENDIF.

  CALL SCREEN 200.
*&---------------------------------------------------------------------*
*&      Module  STATUS_0200  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE status_0200 OUTPUT.

  SET PF-STATUS 'MAIN200'.
  SET TITLEBAR '001'.

  screen_handler=>create_screen( ).

ENDMODULE.                 " STATUS_0200  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0200  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE exit INPUT.

  SET SCREEN 0. LEAVE SCREEN.

ENDMODULE.                 " USER_COMMAND_0200  INPUT

And here's the code from the SCREEN_HANDLER class (as before, is a bit long):


*&---------------------------------------------------------------------*
*&  Include           ZBC_SDN_TREE_AND_ALV_C01
*&---------------------------------------------------------------------*

CLASS screen_handler DEFINITION FINAL CREATE PRIVATE.

  PUBLIC SECTION.
* // Statics
    CLASS-METHODS: create_screen.
    CLASS-DATA:    screen       TYPE REF TO screen_handler.
* // Instance
    METHODS:       constructor.

  PRIVATE SECTION.
    DATA:          container    TYPE REF TO cl_gui_custom_container,
                   splitter     TYPE REF TO cl_gui_easy_splitter_container,
                   left_region  TYPE REF TO cl_gui_container,
                   right_region TYPE REF TO cl_gui_container,
                   tree         TYPE REF TO cl_simple_tree_model,
                   grid         TYPE REF TO cl_gui_alv_grid,
* // Grid details:
                   layo         TYPE lvc_s_layo,
                   vari         TYPE disvariant,
                   fcat         TYPE lvc_t_fcat.

    METHODS:       create_gui_controls,
                   fill_tree,
                   set_layout   IMPORTING table_name  TYPE dd02l-tabname,
                   change_node  IMPORTING iv_node_key TYPE string
                                          iv_icon     TYPE C,
                   handle_node_double_click
                      FOR EVENT node_double_click OF cl_simple_tree_model
                                IMPORTING node_key.

ENDCLASS.                    "screen_handler DEFINITION

*----------------------------------------------------------------------*
*       CLASS screen_handler IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS screen_handler IMPLEMENTATION.

  METHOD create_screen.

    IF screen IS INITIAL.
      CREATE OBJECT screen.
    ENDIF.

  ENDMETHOD.                    "create_screen

  METHOD constructor.

    create_gui_controls( ).
    fill_tree( ).

  ENDMETHOD.                    "constructor

  METHOD create_gui_controls.

* // Create main container
    CREATE OBJECT container EXPORTING container_name = 'CC_ALV'.
* // Split the container in two regions:
    CREATE OBJECT splitter EXPORTING parent        = container
                                     orientation   =
                                        cl_gui_easy_splitter_container=>orientation_horizontal
                                     sash_position = 25.
* // Get the created regions:
    left_region  = splitter->top_left_container.
    right_region = splitter->bottom_right_container.

* // Create display objects: Tree
    CREATE OBJECT tree EXPORTING node_selection_mode =
                  cl_simple_tree_model=>node_sel_mode_single.
    tree->create_tree_control( EXPORTING parent = left_region ).
* // Grid
    CREATE OBJECT grid EXPORTING i_parent = right_region.

  ENDMETHOD.

  METHOD fill_tree.
* // Events: Double Click on leaf
    DATA: sEvent TYPE cntl_simple_event,
          tEvent TYPE cntl_simple_events.
* // Nodes:
    DATA: tNodes TYPE treemsnota,
          sNode  TYPE treemsnodt.

* // Last Author:
    DATA: last_author TYPE dd02l-as4user.

* // Register tree events:
    sEvent-eventid    = cl_simple_tree_model=>eventid_node_double_click.
    sEvent-appl_event = ' '.
    APPEND sEvent TO tEvent.
    tree->set_registered_events( EXPORTING events = tEvent ).
    SET HANDLER me->handle_node_double_click FOR tree.

* // Fill the contents of the tree accordingly to the global_table "tree_table"
    sNode-node_key = 'ROOT'.
    sNode-isfolder = 'X'.
    sNode-text     = 'Selected Tables'(003).
    APPEND sNode TO tNodes.

    LOOP AT tree_table INTO tree_line.
     IF last_author NE tree_line-as4user.
       sNode-node_key  = last_author = tree_line-as4user.
       sNode-relatkey  = 'ROOT'.
       sNode-relatship = cl_tree_model=>relat_last_child.
       sNode-n_image   = icon_led_inactive.
       sNode-text      = tree_line-as4user.
       APPEND sNode TO tNodes.
     ENDIF.
     sNode-node_key    = tree_line-tabname.
     sNode-relatkey    = tree_line-as4user.
     sNode-relatship   = cl_tree_model=>relat_last_child.
     sNode-n_image     = icon_table_settings.
     sNode-text        = tree_line-tabname.
     APPEND sNode TO tNodes.
   ENDLOOP.

* // Add nodes to tree model
   tree->add_nodes( EXPORTING node_table = tNodes ).
* // Expand root nodes
   tree->expand_root_nodes( ).

  ENDMETHOD.

  METHOD change_node.
    "IMPORTING iv_node_key TYPE string
    "          iv_icon     TYPE c

    DATA: sNode         TYPE treemsnodt,
          tUpdateNodes  TYPE treemsunot,
          sUpdateNode   TYPE treemsuno,
          tNodes        TYPE treemnotab,
          oneNode       TYPE tm_nodekey.

* // Properties:
    tree->node_get_properties( EXPORTING node_key   = iv_node_key
                               IMPORTING properties = sNode ).
    sUpdateNode-node_key  = iv_node_key.
    sUpdateNode-n_image   = iv_icon.
    sUpdateNode-u_n_image = 'X'.
    APPEND sUpdateNode TO tUpdateNodes.
* // Set Properties:
    tree->update_nodes( EXPORTING node_table = tUpdateNodes ).

* // Re-Set icons of non-clicked nodes:
    FREE tUpdateNodes.
    tree->get_all_node_keys( IMPORTING node_key_table = tNodes ).
    LOOP AT tNodes INTO oneNode.
      CHECK oneNode NE 'ROOT' AND oneNode NE iv_node_key.
      sUpdateNode-node_key  = oneNode.
      sUpdateNode-n_image   = icon_led_inactive.
      sUpdateNode-u_n_image = 'X'.
      APPEND sUpdateNode TO tUpdateNodes.
    ENDLOOP.

    tree->update_nodes( EXPORTING node_table = tUpdateNodes ).

  ENDMETHOD.

  METHOD handle_node_double_click.
    "IMPORTING node_key TYPE lvc_nkey

    DATA: table_name          TYPE dd02l-tabname,
          refTable            TYPE REF TO data,
          sqlExc              TYPE REF TO cx_sy_dynamic_osql_semantics,
          error               TYPE string.
    FIELD-SYMBOLS: <dynTable> TYPE TABLE.

    CHECK node_key NE 'ROOT'.

* // Get table:
    table_name = node_key.
* // Check if user has clicked an author or a table:
    READ TABLE tree_table WITH KEY tabname = table_name TRANSPORTING NO FIELDS.
    IF sy-subrc EQ 0.
      CREATE DATA refTable TYPE STANDARD TABLE OF (table_name).
      ASSIGN refTable->* TO <dynTable>.
* // Fetch Data:
      TRY.
        SELECT * FROM (table_name) INTO TABLE <dynTable> ORDER BY PRIMARY KEY.
       CATCH cx_sy_dynamic_osql_semantics INTO sqlExc.
         error = sqlExc->get_text( ).
         MESSAGE error TYPE 'I' DISPLAY LIKE 'E'.
         me->change_node( EXPORTING iv_node_key = node_key
                                    iv_icon     = icon_led_red ).
         RETURN.
      ENDTRY.
* // Set layout:
      me->set_layout( table_name ).
* // Fielcatalog non needed, are all ddic structures:
      grid->set_table_for_first_display( EXPORTING i_structure_name = table_name
                                                   is_layout        = layo
                                                   is_variant       = vari
                                                   i_save           = 'A'
                                         CHANGING  it_outtab        = <dynTable> ).
* // Set icon
      me->change_node( EXPORTING iv_node_key = node_key
                                 iv_icon     = icon_led_green ).
    ENDIF.
  ENDMETHOD.

  METHOD set_layout.
    "IMPORTING table_name TYPE dd02l-tabname

    layo-zebra = 'X'.
    CONCATENATE 'Clicked Table'(004) table_name INTO layo-grid_title
      SEPARATED BY space.
    vari-report = sy-repid.

  ENDMETHOD.

ENDCLASS.                    "screen_handler IMPLEMENTATION

Hope this helps,

Roby.

0 Kudos
541

Hi Roby,

this is exactly my application layout. Thank you very much for your example and your effort. I copied it in my system and the application is working. The data is being refreshed.

Also a prior version from me worked in the same way. But I was not satisfied. Please use your application and store a user defined layout as default. Now click on another table node. You will see that no data is displayed because of course the new table has a different structure. Therefore I thought that for every table structure a new alv instance has to be generated. But when you do this the data is not refreshed. Perhaps there is another way to reach this target.

The question is how can I use the dynamic ALV where the stored default layout is correct.

Best Regards and thank you very much, Edgar

0 Kudos
541

I think that even generating multiple instances the whole thing will not work..simply because variant management works on Program, therefore any variant will be applicable for each report, regardless of the table you are displaying.

I'm trying to work on the field HANDLE of structure DISVARIANT to check out if there is some kind of "workaround"..

0 Kudos
541

Hello Edgar

I modified the sample report by Roberto in order to fulfill your layout requirement.


* // Get tables based on selscreen parameters:
  SELECT as4user tabname INTO CORRESPONDING FIELDS OF TABLE tree_table
                         FROM  dd02l
                         WHERE tabname  IN s_table
                         AND   as4local EQ 'A' "Active Object
                         AND   as4user  IN s_user
                         AND   tabclass EQ 'TRANSP'.
  IF sy-subrc NE 0.
    MESSAGE 'No tables for the choosen parameters'(002) TYPE 'E'.
  ENDIF.

" NOTE: Otherwise report dumps when selected with no user and tabname = 'VB*' for example
  SORT tree_table BY as4user tabname. 


  METHOD set_layout.
    "IMPORTING table_name TYPE dd02l-tabname

    layo-zebra = 'X'.
    CONCATENATE 'Clicked Table'(004) table_name INTO layo-grid_title
      SEPARATED BY space.


**    vari-report = sy-repid.
    vari-report = table_name.  " !!!  The system does not care about this name
    vari-handle = 'GRID'.

  ENDMETHOD.

Regards,

Uwe

0 Kudos
541

Hello Edgar

I modified the sample report by Roberto in order to fulfill your layout requirement.


* // Get tables based on selscreen parameters:
  SELECT as4user tabname INTO CORRESPONDING FIELDS OF TABLE tree_table
                         FROM  dd02l
                         WHERE tabname  IN s_table
                         AND   as4local EQ 'A' "Active Object
                         AND   as4user  IN s_user
                         AND   tabclass EQ 'TRANSP'.
  IF sy-subrc NE 0.
    MESSAGE 'No tables for the choosen parameters'(002) TYPE 'E'.
  ENDIF.

" NOTE: Otherwise report dumps when selected with no user and tabname = 'VB*' for example
  SORT tree_table BY as4user tabname. 


  METHOD set_layout.
    "IMPORTING table_name TYPE dd02l-tabname

    layo-zebra = 'X'.
    CONCATENATE 'Clicked Table'(004) table_name INTO layo-grid_title
      SEPARATED BY space.


**    vari-report = sy-repid.
    vari-report = table_name.  " !!!  The system does not care about this name
    vari-handle = 'GRID'.

  ENDMETHOD.

Regards,

Uwe

0 Kudos
541

Hi Uwe,

now it works. Great!!!!!

Thank you for your contribution. Roby and you solved the problem.

Best Regards, Edgar

0 Kudos
541

Hi Roby,

Uwe found the final solution. Thanks a lot for your great contribution.

Best Regards, Edgar

0 Kudos
541

Hello Edgar

There is at least one obvious drawback of my solution: you cannot transport ALV layouts along with your report. However, I think you and your application users can live with that.

Regards,

Uwe

0 Kudos
541

Hi Uwe,

thanks for this hint, but as you said I can live with this limitation....

Best Regards, Edgar

0 Kudos
541

Hi Uwe and the others-- Thanks for the effort involved

this method worked fine

Jimbo

0 Kudos
541

Hello James

I assume you are still working on 4.6c. Then you have to change your coding accordingly since at this release certain abbreviated coding statements are not yet available:


METHOD constructor.

"create_gui_controls( ).   " syntax error on 4.6c
"fill_tree( ).

  CALL METHOD create_gui_controls( ).  " not sure if you have to add the class name, too
  CALL METHOD fill_tree( ).

ENDMETHOD. "constructor

Kind Regards,

Uwe

0 Kudos
541

Hi Uwe your mods worked fine on 4.6

working on both 4.6 (phasing out) and ECC 6.0.

Normally I do the code on 6.0 and try and "Backport" if required.

Thanks for the loads of useful tips you provide on these forums.

Your work is much appreciated

Cheers

Jimbo

uwe_schieferstein
Active Contributor
0 Kudos
541

Hello Edgar

The following sample report <b>ZUS_SDN_TWO_ALV_GRIDS_8</b> shows how to solve your problem. Please note that for the sake of simplicity I replaced the tree containing the structure names with an ALV list. However, the switch between the different structures is triggered by the <b>DOUBLE_CLICK</b> event.

I like to add that the integration of the first displayed ALV list (DD02L) into GT_OUTTAB is not really elegant. In addition, with <b>$TMP</b> I marked a problematic part of the coding with respect to your requirement to have the right layout for each displayed ALV list:

If you have a <b>fixed </b>assignment of <i>tabname -> 4-digit handle</i> then it is ok. I my sample report the layouts only work if you select the tabnames in the very same order.

Before showing the entire coding I describe crucial parts of the coding:

[code]TYPES: BEGIN OF ty_s_outtab.

TYPES: tabname TYPE tabname.

TYPES: layout TYPE lvc_s_layo.

TYPES: variant TYPE disvariant.

TYPES: fcat TYPE lvc_t_fcat.

TYPES: data TYPE REF TO data.

TYPES: END OF ty_s_outtab.[/code]

Every time a new structure is selected the corresponding ALV data are stored as new record in GT_OUTTAB which is of line type TY_S_OUTTAB.

[code] READ TABLE gt_outtab INTO gs_outtab INDEX 2.

ASSIGN gs_outtab-fcat TO <gt_fcat>.

ASSIGN gs_outtab-data->* TO <gt_outtab>.[/code]

Since the ALV list data and the fieldcatalog are fully dynamic I use global field-symbols for these data.

[code]&----


*& Module STATUS_0100 OUTPUT

&----


  • text

----


MODULE status_0100 OUTPUT.

SET PF-STATUS 'STATUS_0100'. " contains push button "DETAIL"

  • SET TITLEBAR 'xxx'.

CALL METHOD go_grid2->set_table_for_first_display

EXPORTING

i_structure_name = gs_outtab-tabname

is_layout = gs_outtab-layout

is_variant = gs_outtab-variant

i_save = 'A'

CHANGING

it_outtab = <gt_outtab>

it_fieldcatalog = <gt_fcat>

EXCEPTIONS

OTHERS = 4.

IF sy-subrc <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

  • WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

ENDIF.

ENDMODULE. " STATUS_0100 OUTPUT[/code]

The second ALV list which displays the table records is always newly displayed in the PBO module.

In the event handler method <b>HANDLE_DOUBLE_CLICK</b> we need to do two things:

- store the current fieldcatalog back to GT_OUTTAB

- store the name of the new selected table/structure -> trigger PAI

In routine <b>HANDLE_DB_CLICK</b> we create a new entry for GT_OUTTAB if it does not yet exist. Next we select this entry and display it again as second ALV list.

[code]

&----


*& Report ZUS_SDN_TWO_ALV_GRIDS_8

*&

*& Description: Display two ALV lists in splitter container (left/right)

*& Left ALV list contains DB table names,

*& right ALV list displays entries of selected DB table

*&

*& SDN thread: Dynamical Call of ALV - No data update

*& Link: https:||

&----


*& Screen '0100' contains no elements.

*& ok_code -> assigned to GD_OKCODE

*&

*& Flow logic:

  • PROCESS BEFORE OUTPUT.

  • MODULE STATUS_0100.

**

  • PROCESS AFTER INPUT.

  • MODULE USER_COMMAND_0100.

*&

&----


REPORT zus_sdn_two_alv_grids_8.

TYPE-POOLS: abap.

DATA:

gd_repid TYPE syst-repid,

gd_okcode TYPE ui_func,

*

go_docking TYPE REF TO cl_gui_docking_container,

go_splitter TYPE REF TO cl_gui_splitter_container,

go_cell_left TYPE REF TO cl_gui_container,

go_cell_right TYPE REF TO cl_gui_container,

go_grid1 TYPE REF TO cl_gui_alv_grid,

go_grid2 TYPE REF TO cl_gui_alv_grid,

gs_layout TYPE lvc_s_layo.

TYPES: BEGIN OF ty_s_outtab.

TYPES: tabname TYPE tabname.

TYPES: layout TYPE lvc_s_layo.

TYPES: variant TYPE disvariant.

TYPES: fcat TYPE lvc_t_fcat.

TYPES: data TYPE REF TO data.

TYPES: END OF ty_s_outtab.

TYPES: ty_t_outtab TYPE STANDARD TABLE OF ty_s_outtab

WITH DEFAULT KEY.

DATA:

gt_dd02l TYPE STANDARD TABLE OF dd02l,

gs_outtab TYPE ty_s_outtab,

gt_outtab TYPE ty_t_outtab.

FIELD-SYMBOLS:

<gt_fcat> TYPE lvc_t_fcat,

<gt_outtab> TYPE table.

----


  • CLASS lcl_eventhandler DEFINITION

----


*

----


CLASS lcl_eventhandler DEFINITION.

PUBLIC SECTION.

CLASS-DATA:

md_tabname_selected TYPE tabname READ-ONLY.

CLASS-METHODS:

handle_double_click FOR EVENT double_click OF cl_gui_alv_grid

IMPORTING

e_row

e_column

es_row_no

sender.

ENDCLASS. "lcl_eventhandler DEFINITION

----


  • CLASS lcl_eventhandler IMPLEMENTATION

----


*

----


CLASS lcl_eventhandler IMPLEMENTATION.

METHOD handle_double_click.

  • define local data

DATA:

ls_dd02l TYPE dd02l,

ls_outtab TYPE ty_s_outtab.

CHECK ( sender = go_grid1 ).

READ TABLE gt_dd02l INTO ls_dd02l INDEX e_row-index.

" Store data of currently displayed ALV list (except for DD02L)

IF ( md_tabname_selected = space ).

ELSE.

READ TABLE gt_outtab INTO ls_outtab

WITH KEY tabname = md_tabname_selected. " old

CALL METHOD go_grid2->get_frontend_fieldcatalog

IMPORTING

et_fieldcatalog = ls_outtab-fcat.

MODIFY gt_outtab FROM ls_outtab INDEX syst-tabix.

ENDIF.

md_tabname_selected = ls_dd02l-tabname. " new selected DB table

  • Triggers PAI of the dynpro with the specified ok-code

    • cl_gui_cfw=>set_new_ok_code( 'HANDLE_DB_CLICK' ). " not 4.6c

CALL METHOD cl_gui_cfw=>set_new_ok_code

EXPORTING

new_code = 'HANDLE_DB_CLICK'

  • IMPORTING

  • RC =

.

ENDMETHOD. "handle_double_click

ENDCLASS. "lcl_eventhandler IMPLEMENTATION

START-OF-SELECTION.

gd_repid = syst-repid.

SELECT * FROM dd02l INTO TABLE gt_dd02l

WHERE tabname LIKE 'KN%1' OR

tabname LIKE 'LF%1' OR

tabname LIKE 'VB%' OR

tabname LIKE 'MAR%' OR

tabname LIKE 'E07%'

AND tabclass = 'TRANSP'. " transparent table

SORT gt_dd02l BY tabname.

PERFORM init_controls.

PERFORM add_first_table.

  • Set event handler

SET HANDLER:

lcl_eventhandler=>handle_double_click FOR go_grid1.

READ TABLE gt_outtab INTO gs_outtab INDEX 1.

  • Display data

CALL METHOD go_grid1->set_table_for_first_display

EXPORTING

i_structure_name = gs_outtab-tabname

is_layout = gs_outtab-layout

CHANGING

it_outtab = gt_dd02l

EXCEPTIONS

OTHERS = 4.

IF sy-subrc <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

  • WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

ENDIF.

READ TABLE gt_outtab INTO gs_outtab INDEX 2.

ASSIGN gs_outtab-fcat TO <gt_fcat>.

ASSIGN gs_outtab-data->* TO <gt_outtab>.

  • NOTE: method called in PBO module

    • CALL METHOD go_grid2->set_table_for_first_display

    • EXPORTING

    • i_structure_name = gs_outtab-tabname

    • is_layout = gs_outtab-layout

    • is_variant = gs_outtab-variant

    • i_save = 'A'

    • CHANGING

    • it_outtab = <gt_outtab>

    • it_fieldcatalog = <gt_fcat>

    • EXCEPTIONS

    • OTHERS = 4.

    • IF sy-subrc <> 0.

      • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

      • WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

    • ENDIF.

  • Link the docking container to the target dynpro

CALL METHOD go_docking->link

EXPORTING

repid = gd_repid

dynnr = '0100'

  • CONTAINER =

EXCEPTIONS

OTHERS = 4.

IF sy-subrc <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

  • WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

ENDIF.

  • NOTE: dynpro does not contain any elements

CALL SCREEN '0100'.

  • Flow logic of dynpro (does not contain any dynpro elements):

*

*PROCESS BEFORE OUTPUT.

  • MODULE STATUS_0100.

**

*PROCESS AFTER INPUT.

  • MODULE USER_COMMAND_0100.

END-OF-SELECTION.

&----


*& Module STATUS_0100 OUTPUT

&----


  • text

----


MODULE status_0100 OUTPUT.

SET PF-STATUS 'STATUS_0100'. " contains push button "DETAIL"

  • SET TITLEBAR 'xxx'.

CALL METHOD go_grid2->set_table_for_first_display

EXPORTING

i_structure_name = gs_outtab-tabname

is_layout = gs_outtab-layout

is_variant = gs_outtab-variant

i_save = 'A'

CHANGING

it_outtab = <gt_outtab>

it_fieldcatalog = <gt_fcat>

EXCEPTIONS

OTHERS = 4.

IF sy-subrc <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

  • WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

ENDIF.

ENDMODULE. " STATUS_0100 OUTPUT

&----


*& Module USER_COMMAND_0100 INPUT

&----


  • text

----


MODULE user_command_0100 INPUT.

CASE gd_okcode.

WHEN 'BACK' OR

'END' OR

'CANC'.

SET SCREEN 0. LEAVE SCREEN.

  • User has pushed button "Display Details"

WHEN 'HANDLE_DB_CLICK'.

PERFORM handle_db_click.

WHEN OTHERS.

ENDCASE.

CLEAR: gd_okcode.

ENDMODULE. " USER_COMMAND_0100 INPUT

&----


*& Form HANDLE_DB_CLICK

&----


  • text

----


  • --> p1 text

  • <-- p2 text

----


FORM handle_db_click.

  • define local data

DATA:

ld_handle(4) TYPE n,

ls_outtab TYPE ty_s_outtab.

READ TABLE gt_outtab INTO ls_outtab

WITH KEY tabname = lcl_eventhandler=>md_tabname_selected.

IF ( syst-subrc NE 0 ).

CLEAR: ls_outtab.

ls_outtab-tabname = lcl_eventhandler=>md_tabname_selected.

CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'

EXPORTING

  • I_BUFFER_ACTIVE =

i_structure_name = ls_outtab-tabname

  • I_CLIENT_NEVER_DISPLAY = 'X'

  • I_BYPASSING_BUFFER =

  • I_INTERNAL_TABNAME =

CHANGING

ct_fieldcat = ls_outtab-fcat

EXCEPTIONS

inconsistent_interface = 1

program_error = 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.

ENDIF.

CREATE DATA ls_outtab-data TYPE TABLE OF (ls_outtab-tabname).

ASSIGN ls_outtab-data->* TO <gt_outtab>.

SELECT * FROM (ls_outtab-tabname) UP TO 50 ROWS

INTO TABLE <gt_outtab>.

ls_outtab-layout-no_toolbar = abap_false.

ls_outtab-layout-zebra = abap_true.

ls_outtab-layout-smalltitle = abap_true.

CONCATENATE ls_outtab-tabname ':'

INTO ls_outtab-layout-grid_title.

CONCATENATE ls_outtab-layout-grid_title 'Table Records'

INTO ls_outtab-layout-grid_title

SEPARATED BY space.

ls_outtab-variant-report = gd_repid.

DESCRIBE TABLE gt_outtab.

ld_handle = syst-tfill + 1.

WRITE ld_handle TO ls_outtab-variant-handle. " $TMP: Problem!!!

APPEND ls_outtab TO gt_outtab.

ENDIF.

" NOTE: read into GLOBAL variable gs_outtab !!!!

READ TABLE gt_outtab INTO gs_outtab

WITH KEY tabname = lcl_eventhandler=>md_tabname_selected.

ASSIGN gs_outtab-fcat TO <gt_fcat>.

ASSIGN gs_outtab-data->* TO <gt_outtab>.

ENDFORM. " HANDLE_DB_CLICK

&----


*& Form INIT_CONTROLS

&----


  • text

----


  • --> p1 text

  • <-- p2 text

----


FORM init_controls .

  • Create docking container

CREATE OBJECT go_docking

EXPORTING

parent = cl_gui_container=>screen0

ratio = 90

EXCEPTIONS

OTHERS = 6.

IF sy-subrc <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

  • WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

ENDIF.

CALL METHOD go_docking->set_extension

EXPORTING

extension = 99999 " full-size screen

EXCEPTIONS

cntl_error = 1

OTHERS = 2.

IF sy-subrc <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

  • WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

ENDIF.

  • Create splitter container

CREATE OBJECT go_splitter

EXPORTING

parent = go_docking

rows = 1

columns = 2

  • NO_AUTODEF_PROGID_DYNNR =

  • NAME =

EXCEPTIONS

cntl_error = 1

cntl_system_error = 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.

ENDIF.

  • Get cell container

CALL METHOD go_splitter->get_container

EXPORTING

row = 1

column = 1

RECEIVING

container = go_cell_left.

CALL METHOD go_splitter->get_container

EXPORTING

row = 1

column = 2

RECEIVING

container = go_cell_right.

CALL METHOD go_splitter->set_column_mode

EXPORTING

mode = cl_gui_splitter_container=>mode_relative

  • IMPORTING

  • RESULT =

EXCEPTIONS

cntl_error = 1

cntl_system_error = 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.

ENDIF.

CALL METHOD go_splitter->set_column_width

EXPORTING

id = 1

width = 25

  • IMPORTING

  • RESULT =

EXCEPTIONS

cntl_error = 1

cntl_system_error = 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.

ENDIF.

CALL METHOD go_splitter->set_column_sash

EXPORTING

id = 1

type = cl_gui_splitter_container=>type_movable

value = cl_gui_splitter_container=>false

  • IMPORTING

  • RESULT =

EXCEPTIONS

cntl_error = 1

cntl_system_error = 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.

ENDIF.

  • Create ALV grids

CREATE OBJECT go_grid1

EXPORTING

i_parent = go_cell_left

EXCEPTIONS

OTHERS = 5.

IF sy-subrc <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

  • WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

ENDIF.

CREATE OBJECT go_grid2

EXPORTING

i_parent = go_cell_right

EXCEPTIONS

OTHERS = 5.

IF sy-subrc <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

  • WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

ENDIF.

ENDFORM. " INIT_CONTROLS

&----


*& Form ADD_FIRST_TABLE

&----


  • text

----


  • --> p1 text

  • <-- p2 text

----


FORM add_first_table .

  • define local data

DATA:

ls_outtab TYPE ty_s_outtab.

ls_outtab-tabname = 'DD02L'.

CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'

EXPORTING

  • I_BUFFER_ACTIVE =

i_structure_name = ls_outtab-tabname

  • I_CLIENT_NEVER_DISPLAY = 'X'

  • I_BYPASSING_BUFFER =

  • I_INTERNAL_TABNAME =

CHANGING

ct_fieldcat = ls_outtab-fcat

EXCEPTIONS

inconsistent_interface = 1

program_error = 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.

ENDIF.

GET REFERENCE OF gt_dd02l INTO ls_outtab-data.

ls_outtab-layout-no_toolbar = abap_false.

ls_outtab-layout-zebra = abap_true.

ls_outtab-layout-smalltitle = abap_true.

CONCATENATE ls_outtab-tabname ':'

INTO ls_outtab-layout-grid_title.

CONCATENATE ls_outtab-layout-grid_title 'Table Records'

INTO ls_outtab-layout-grid_title

SEPARATED BY space.

ls_outtab-variant-report = gd_repid.

ls_outtab-variant-handle = '0002'.

INSERT ls_outtab INTO gt_outtab INDEX 1.

ls_outtab-layout-no_toolbar = abap_true.

  • ls_outtab-layout-zebra = abap_true.

  • ls_outtab-layout-smalltitle = abap_true.

ls_outtab-layout-grid_title = 'DB Tables'.

  • ls_outtab-variant-report = gd_repid.

ls_outtab-variant-handle = '0001'.

DELETE ls_outtab-fcat WHERE ( fieldname NE 'TABNAME' ).

INSERT ls_outtab INTO gt_outtab INDEX 1.

ENDFORM. " ADD_FIRST_TABLE[/code]

Regards,

Uwe

0 Kudos
541

Hi Uwe,

thank you again for this nice example. I will keep it in mind.

Unfortunately I can't change my current screen layout. Your example uses two ALV grids.

In my layout I have one simple tree on the left side of the screen and one alv tree for displaying the tree data on the right side of the screen. The display structure changes for every hierachy level of the tree. The tree hierarchy can be always diffrent for every call of the program. The controls are embedded in a splitter container, because the size of the tree/alv screen should be changed by the user. Additionally I want that the screen layouts of the ALV can be saved by the user.

Looking on my thread I suppose that the splitter container has a bug. Currently there is one really big example in the thread, which uses my layout. I have to examine this....

Best regards and thak you

Edgar