06-16-2009 10:30 AM
Hi Gurus!!
I have a issue with a cl_salv_table=>factory attached to a Docking Container.
Here is my code set up, which might be wrong actually:
I've created a simple report, with a TOP and some include for PBO, PAI and routines. In the Report, I call a Screen, here 2000.
The TOP contains
DATA: docking_container TYPE REF TO cl_gui_docking_container,
gc_table_alv TYPE REF TO cl_salv_table.
The Screen Flow is basic:
PROCESS BEFORE OUTPUT.
MODULE status_2000.
*
PROCESS AFTER INPUT.
MODULE user_command_2000.
With status_2000:
MODULE status_2000 OUTPUT.
SET PF-STATUS 'STATUS'.
* SET TITLEBAR 'xxx'.
* Initialization of docking container
IF docking_container IS INITIAL.
CREATE OBJECT docking_container
EXPORTING
side = cl_gui_docking_container=>dock_at_bottom
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0. MESSAGE a500. ENDIF.
CALL METHOD docking_container->set_height
EXPORTING
height = 170.
ENDIF.
ENDMODULE. " STATUS_2000 OUTPUT
Then the Screen PAI looks dumb, but in this example, I have drastically made the code simpler
06-16-2009 10:31 AM
-CONTINUED-
Basically, at runtime, screen is displayed, with the empty docking container. When Enter is pressed for the 1st time, a Select and display method is used. Then, when Enter is pressed a 2nd time, the display is expected to refresh the ALV with new data and a new structure. But it's not!
Actually, it's working when I use cl_gui_alv_grid attached to the docking container, instead. But I have to fill the ALV Field Catalog by myself.
Any advice to make it work or to set my code differently is welcome !
MODULE user_command_2000 INPUT.
* UCOMM management
CASE sy-ucomm.
WHEN 'BACK' OR 'CANCEL'.
LEAVE TO SCREEN 0.
WHEN 'EXIT'.
LEAVE PROGRAM.
ENDCASE.
* Variables
DATA: count TYPE i, " Simple Counter
lt_vbrk TYPE TABLE OF vbrk, " Data Table 1
tl_ekpo TYPE TABLE OF ekpo. " Data Table 2
IMPORT count TO count FROM MEMORY ID 'TEST'.
IF count IS INITIAL.
* Population of Table 1
SELECT * INTO TABLE lt_vbrk FROM vbrk UP TO 1 ROWS.
* Creation of ALV, docked
CALL METHOD cl_salv_table=>factory
EXPORTING
r_container = docking_container
IMPORTING
r_salv_table = gc_table_alv
CHANGING
t_table = lt_vbrk.
* ALV Display
gc_table_alv->display( ).
ENDIF.
IF count EQ 1.
* Population of Table 2
SELECT * INTO TABLE tl_ekpo FROM ekpo UP TO 1 ROWS.
* Creation of ALV, docked
CALL METHOD cl_salv_table=>factory
EXPORTING
r_container = docking_container
IMPORTING
r_salv_table = gc_table_alv
CHANGING
t_table = tl_ekpo.
* ALV Display
gc_table_alv->display( ).
ENDIF.
* Counter increment
ADD 1 TO count.
EXPORT count FROM count TO MEMORY ID 'TEST'.
ENDMODULE. " USER_COMMAND_2000 INPUT
06-16-2009 10:31 AM
-CONTINUED-
Basically, at runtime, screen is displayed, with the empty docking container. When Enter is pressed for the 1st time, a Select and display method is used. Then, when Enter is pressed a 2nd time, the display is expected to refresh the ALV with new data and a new structure. But it's not!
Actually, it's working when I use cl_gui_alv_grid attached to the docking container, instead. But I have to fill the ALV Field Catalog by myself.
Any advice to make it work or to set my code differently is welcome !
MODULE user_command_2000 INPUT.
* UCOMM management
CASE sy-ucomm.
WHEN 'BACK' OR 'CANCEL'.
LEAVE TO SCREEN 0.
WHEN 'EXIT'.
LEAVE PROGRAM.
ENDCASE.
* Variables
DATA: count TYPE i, " Simple Counter
lt_vbrk TYPE TABLE OF vbrk, " Data Table 1
tl_ekpo TYPE TABLE OF ekpo. " Data Table 2
IMPORT count TO count FROM MEMORY ID 'TEST'.
IF count IS INITIAL.
* Population of Table 1
SELECT * INTO TABLE lt_vbrk FROM vbrk UP TO 1 ROWS.
* Creation of ALV, docked
CALL METHOD cl_salv_table=>factory
EXPORTING
r_container = docking_container
IMPORTING
r_salv_table = gc_table_alv
CHANGING
t_table = lt_vbrk.
* ALV Display
gc_table_alv->display( ).
ENDIF.
IF count EQ 1.
* Population of Table 2
SELECT * INTO TABLE tl_ekpo FROM ekpo UP TO 1 ROWS.
* Creation of ALV, docked
CALL METHOD cl_salv_table=>factory
EXPORTING
r_container = docking_container
IMPORTING
r_salv_table = gc_table_alv
CHANGING
t_table = tl_ekpo.
* ALV Display
gc_table_alv->display( ).
ENDIF.
* Counter increment
ADD 1 TO count.
EXPORT count FROM count TO MEMORY ID 'TEST'.
ENDMODULE. " USER_COMMAND_2000 INPUT
06-16-2009 11:06 AM
Since the two ALVs must reside in one docking container, it might be problematic to change the structure.
If there was only one strcutre you could use dipaly + rehresh methods in turn. but here it is different.
First you create one instance of ALV. This creates corresponding proxy object on presentation server side. As long as your first object is linked to that container it seems that it doesn't allow you to bind another alv with the same container. First, proxy objects binding (first ALV and container) should be released, then new binding can be created and set on presentation server.
What I suggest here is trying to create new docking container within PAI simultaneously with ALV creation.
"in PAI
if count is initial.
"create docking container + first ALV
else.
"release docking container with FREE method
"create new docking container + second ALV
endif.
This unfortunatelly will not provide container at first PBO execution so empty screen is set by default, but once you trigger any action it will keep creating new pair container + alv and that might work.
Please check that.
Regards
Marcin
06-16-2009 11:37 AM
Hi Marcin,
Thx for your answer.
Unfortunately, this solution doesn't get rid of the 1st docking container, but add another one at the top of the screen. It looks like the bottom part of the screen is not available anymore.
What is weird, is that if I use cl_gui_alv_grid in the PBO with
CREATE OBJECT alv_grid_container
EXPORTING
parent = docking_container.
then in the PAI I would use
CALL METHOD alv_grid_container->set_table_for_first_display
EXPORTING
is_layout = ls_layout
i_save = 'U'
CHANGING
it_outtab = lt_outtab
it_fieldcatalog = lt_fieldcat.
with that set up, everytime, the ALV in the Docking Container is refreshed. But the drawback is that I have to handle the Field Catalog. Unless there's a simple way to generate it?
06-16-2009 11:56 AM
I think you are not releasing proxy object with method FREE of docking container.
Check the below code. It first displays SFLIGHT table, then after another dialog step is concluded, it shows SPFLI table.
DATA: r_dock_container TYPE REF TO cl_gui_docking_container,
r_salv_table TYPE REF TO cl_salv_table.
DATA: it_sflight TYPE sflight OCCURS 0,
it_spfli TYPE spfli OCCURS 0.
DATA: count TYPE i.
START-OF-SELECTION.
SELECT * FROM sflight INTO TABLE it_sflight UP TO 10 ROWS.
SELECT * FROM spfli INTO TABLE it_spfli UP TO 10 ROWS.
CALL SCREEN 0200.
MODULE pbo OUTPUT.
SET PF-STATUS space.
IF count IS INITIAL.
CREATE OBJECT r_dock_container
EXPORTING
side = cl_gui_docking_container=>dock_at_bottom
EXCEPTIONS
OTHERS = 1.
CALL METHOD r_dock_container->set_height
EXPORTING
height = 170.
CALL METHOD cl_salv_table=>factory
EXPORTING
r_container = r_dock_container
IMPORTING
r_salv_table = r_salv_table
CHANGING
t_table = it_sflight.
* ALV Display
r_salv_table->display( ).
ELSE.
r_dock_container->free( ). "this is crucial to release proxy object of docking container
CLEAR r_dock_container. "and clear a reference variable (with these two statements your control will disapear from screen)
"now you can create a new one and bound a new ALV to it
CREATE OBJECT r_dock_container
EXPORTING
side = cl_gui_docking_container=>dock_at_bottom
EXCEPTIONS
OTHERS = 1.
CALL METHOD r_dock_container->set_height
EXPORTING
height = 170.
CALL METHOD cl_salv_table=>factory
EXPORTING
r_container = r_dock_container
IMPORTING
r_salv_table = r_salv_table
CHANGING
t_table = it_spfli.
* ALV Display
r_salv_table->display( ).
ENDIF.
ADD 1 TO count .
ENDMODULE.
Of course you have to adjust it with your tables and data, but this works fine
Regards
Marcin
Edited by: Marcin Pciak on Jun 16, 2009 12:57 PM
06-16-2009 12:34 PM
Indeed that worked!
Looks like it's smoother with the cl_gui_alv_grid attached to the Docking Container, but I guess I'm gonna stick with your solution.
Well, I have some subsidiary question regarding the cl_salv_table, but I'll make a new post.
Thx a lot Marcin!