2007 Dec 14 9:08 AM
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
2007 Dec 14 9:45 AM
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
2007 Dec 14 9:31 AM
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
2007 Dec 14 12:44 PM
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?
2007 Dec 14 9:45 AM
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
2007 Dec 14 12:55 PM
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
2007 Dec 14 3:00 PM
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..
2007 Dec 14 3:03 PM
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.
2007 Dec 14 3:20 PM
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
2007 Dec 14 3:37 PM
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
2007 Dec 14 4:33 PM
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.
2007 Dec 17 7:30 AM
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
2007 Dec 17 8:24 AM
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
2007 Dec 17 10:10 AM
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
2007 Dec 17 11:40 AM
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
2007 Dec 17 11:56 AM
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
2007 Dec 17 12:03 PM
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..
2007 Dec 17 2:31 PM
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.
2007 Dec 17 4:30 PM
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
2007 Dec 18 12:46 AM
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"..
2007 Dec 18 4:48 AM
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
2007 Dec 18 4:53 AM
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
2007 Dec 18 10:01 AM
Hi Uwe,
now it works. Great!!!!!
Thank you for your contribution. Roby and you solved the problem.
Best Regards, Edgar
2007 Dec 18 10:03 AM
Hi Roby,
Uwe found the final solution. Thanks a lot for your great contribution.
Best Regards, Edgar
2007 Dec 18 10:04 AM
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
2007 Dec 18 10:10 AM
Hi Uwe,
thanks for this hint, but as you said I can live with this limitation....
Best Regards, Edgar
2007 Dec 18 2:30 PM
Hi Uwe and the others-- Thanks for the effort involved
this method worked fine
Jimbo
2007 Dec 18 2:35 PM
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
2007 Dec 19 9:21 AM
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
2007 Dec 15 9:36 PM
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
&----
*& 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
2007 Dec 17 8:19 AM
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