2007 May 22 9:29 AM
Hello All,
Is it possible to have a user input in ALV grid. I know there can be editable columns/cells but suppose the application demands an input field to be placed in ALV Grid where the user will enter some value.
Could someone please suggest if this can be done.
Regards
Indrajit
2007 May 22 1:42 PM
Hi,
This is one sample program for your query.
DATA: g_container TYPE scrfname VALUE 'CUSTOM CONTROL',
g_custom_container TYPE REF TO cl_gui_custom_container,
g_grid TYPE REF TO cl_gui_alv_grid,
gs_layout TYPE lvc_s_layo,
ok_code LIKE sy-ucomm,
save_ok LIKE sy-ucomm.
DATA: gt_outtab TYPE TABLE OF sflight.
*----
*
MAIN *
*----
*
CALL SCREEN 100 STARTING AT 1 1..
*&----
*
*& Module STATUS_0100 OUTPUT
*&----
*
MODULE status_0100 OUTPUT.
SET PF-STATUS 'MAIN100'.
SET TITLEBAR 'MAIN100'.
ENDMODULE. " STATUS_0100 OUTPUT
*&----
*
*& Module pbo OUTPUT
*&----
*
MODULE pbo OUTPUT.
IF g_custom_container IS INITIAL.
CREATE OBJECT g_custom_container
EXPORTING
container_name = g_container
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5
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.
CREATE OBJECT g_grid
EXPORTING
i_parent = g_custom_container
EXCEPTIONS
error_cntl_create = 1
error_cntl_init = 2
error_cntl_link = 3
error_dp_create = 4
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.
gs_layout-edit = 'X'.
SELECT * FROM sflight INTO TABLE gt_outtab UP TO 10 ROWS.
*§1.Set status of all cells to editable using the layout structure.
CALL METHOD g_grid->set_table_for_first_display
EXPORTING
i_structure_name = 'SFLIGHT'
is_layout = gs_layout
CHANGING
it_outtab = gt_outtab
EXCEPTIONS
invalid_parameter_combination = 1
program_error = 2
too_many_lines = 3
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.
*§2.Use SET_READY_FOR_INPUT to allow editing initially.
CALL METHOD g_grid->set_ready_for_input
EXPORTING
i_ready_for_input = 1.
ENDIF.
ENDMODULE. " pbo OUTPUT
*&----
*
*& Module pai INPUT
*&----
*
MODULE pai INPUT.
save_ok = ok_code.
CLEAR ok_code.
CASE save_ok.
WHEN 'EXIT'.
PERFORM exit_program.
WHEN 'SWITCH'.
PERFORM switch_edit_mode.
WHEN OTHERS.
do nothing
ENDCASE.
ENDMODULE. " pai INPUT
*&----
*
*& Form exit_program
*&----
*
FORM exit_program .
LEAVE PROGRAM.
ENDFORM. " exit_program
*&----
*
*& Form switch_edit_mode
*&----
*
FORM switch_edit_mode .
*§3.Use IS_READY_FOR_INPUT to fetch current substate of editable cells.
IF g_grid->is_ready_for_input( ) EQ 0.
CALL METHOD g_grid->set_ready_for_input
EXPORTING
i_ready_for_input = 1.
ELSE.
CALL METHOD g_grid->set_ready_for_input
EXPORTING
i_ready_for_input = 0.
ENDIF.
ENDFORM. " switch_edit_mode
For More Info, Check this link.
Then you can capture the events in USER COMMAND.
Award if useful
Regards,
Jackie..
Message was edited by:
Jackie Chan
Hello All,
Is it possible to have a user input in ALV grid. I know there can be editable columns/cells but suppose the application demands an input field to be placed in ALV Grid where the user will enter some value.
Could someone please suggest if this can be done.
Regards
Indrajit
2007 May 22 10:41 AM
hi,
check these sites.
How do I create and use input-enabled fields in ALV?
2007 May 22 11:02 AM
2007 May 22 1:42 PM
Hi,
This is one sample program for your query.
DATA: g_container TYPE scrfname VALUE 'CUSTOM CONTROL',
g_custom_container TYPE REF TO cl_gui_custom_container,
g_grid TYPE REF TO cl_gui_alv_grid,
gs_layout TYPE lvc_s_layo,
ok_code LIKE sy-ucomm,
save_ok LIKE sy-ucomm.
DATA: gt_outtab TYPE TABLE OF sflight.
*----
*
MAIN *
*----
*
CALL SCREEN 100 STARTING AT 1 1..
*&----
*
*& Module STATUS_0100 OUTPUT
*&----
*
MODULE status_0100 OUTPUT.
SET PF-STATUS 'MAIN100'.
SET TITLEBAR 'MAIN100'.
ENDMODULE. " STATUS_0100 OUTPUT
*&----
*
*& Module pbo OUTPUT
*&----
*
MODULE pbo OUTPUT.
IF g_custom_container IS INITIAL.
CREATE OBJECT g_custom_container
EXPORTING
container_name = g_container
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5
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.
CREATE OBJECT g_grid
EXPORTING
i_parent = g_custom_container
EXCEPTIONS
error_cntl_create = 1
error_cntl_init = 2
error_cntl_link = 3
error_dp_create = 4
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.
gs_layout-edit = 'X'.
SELECT * FROM sflight INTO TABLE gt_outtab UP TO 10 ROWS.
*§1.Set status of all cells to editable using the layout structure.
CALL METHOD g_grid->set_table_for_first_display
EXPORTING
i_structure_name = 'SFLIGHT'
is_layout = gs_layout
CHANGING
it_outtab = gt_outtab
EXCEPTIONS
invalid_parameter_combination = 1
program_error = 2
too_many_lines = 3
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.
*§2.Use SET_READY_FOR_INPUT to allow editing initially.
CALL METHOD g_grid->set_ready_for_input
EXPORTING
i_ready_for_input = 1.
ENDIF.
ENDMODULE. " pbo OUTPUT
*&----
*
*& Module pai INPUT
*&----
*
MODULE pai INPUT.
save_ok = ok_code.
CLEAR ok_code.
CASE save_ok.
WHEN 'EXIT'.
PERFORM exit_program.
WHEN 'SWITCH'.
PERFORM switch_edit_mode.
WHEN OTHERS.
do nothing
ENDCASE.
ENDMODULE. " pai INPUT
*&----
*
*& Form exit_program
*&----
*
FORM exit_program .
LEAVE PROGRAM.
ENDFORM. " exit_program
*&----
*
*& Form switch_edit_mode
*&----
*
FORM switch_edit_mode .
*§3.Use IS_READY_FOR_INPUT to fetch current substate of editable cells.
IF g_grid->is_ready_for_input( ) EQ 0.
CALL METHOD g_grid->set_ready_for_input
EXPORTING
i_ready_for_input = 1.
ELSE.
CALL METHOD g_grid->set_ready_for_input
EXPORTING
i_ready_for_input = 0.
ENDIF.
ENDFORM. " switch_edit_mode
For More Info, Check this link.
Then you can capture the events in USER COMMAND.
Award if useful
Regards,
Jackie..
Message was edited by:
Jackie Chan
2007 May 31 2:04 PM
Hai Indrajit
it is very simple, u develop a code as u do for ALV using oops, and on the screen along with custom control place a dictionary input output field, and in the program u declare
tables: vbrk.
and in extracting data write
select * from vbrp into table itab where vbeln = vbrk-vbeln.
2007 May 31 2:46 PM
Hi Indrajit,
If you want to have an input field in the ALV grid, all you have to do is to set the EDIT field of the field catalog structure LVC_T_FCAT,ie.
DATA:ls_fcat TYPE lvc_s_fcat.
ls_fcat-edit = 'X'
.
2007 Jun 01 10:26 AM
Don't forget to CALL METHOD alv->refresh_table_display before you're going to save the user input. Thus, you insure that the latest version is saved!
2007 Jun 01 12:19 PM
Here's THE definitive way to do it.
This little proggy demonstrates the following.
1) Create a DYNAMIC FCAT for an internal table with USER defined fields (i.e non ddic) and colour some columns in the FCAT.
2) Create a DYNAMIC TABLE.
3) Define a subclass of CL_GUI_ALV_GRID so you can access some very useful protected methods and attributes - you can get original and changed table IN ROWS which is a lot easier sometimes than messing around with individual
cells.
4) Create extra buttons on the toolbar.
5) Define EVENT handlers including data change so you can get control when the user enters data. YOU DON'T NEED PAI anymore with event handlers.
6) Call methods in your subclass of CL_GUI_ALV_GRID (you can also call methods in CL_GUI_ALV_GRID by virtue of Inheritance) from methods in your event handler class.
7) Display an editable Grid.
This method will work for almost any conditions you need to use.
I'm sure this covers all the bases -- please reply if any queries.
Run the program, click on the EDIT button and enter your data. Press ENTER when done.
All you need to do is copy this code and create one empty screen (SE51) with a custom container called CCONTAINER1 with the following logic in it.
PROCESS BEFORE OUTPUT.
MODULE STATUS_0100.
*
PROCESS AFTER INPUT.
MODULE USER_COMMAND_0100.
(In the program you don't actually do anything in the PAI as the event handler takes care of this)
Now here's the program
PROGRAM zdynfieldcat.
class zcltest definition deferred. "For field symbol reference.
Simple test of dynamic ITAB with user defined (not ddic) fields
Build dynamic fcat
Table structure obtained via new RTTI functionality
use ALV grid to display and edit.
Create a blank screen 100 with a custom container called CCONTAINER1.
*
Define field symbols as these can't be defined in classes
field-symbols: <dyn_table> type standard table,
<g2> type ref to zcltest,
<g1> type ref to cl_gui_custom_container,
<actual_tab> type standard table,
<outtab> type table,
<fs1> type ANY,
<FS2> TYPE TABLE,
<fs3> type table,
<fs4> type table,
<fs5> type table.
class zcltest definition inheriting from cl_gui_alv_grid.
*
define this as a subclass so we can access the protected attributes
of the superclass cl_gui_alv_grid
public section.
types: g4 type ref to cl_gui_custom_container.
types: g3 type ref to cl_alv_changed_data_protocol.
data: i_parent type g4,
lr_rtti_struc TYPE REF TO cl_abap_structdescr, "RTTI
zog like line of lr_rtti_struc->components. "RTTI
types: struc like zog.
types: struc1 type table of struc.
methods:
constructor
importing i_parent type g4,
disp_tab
importing p_er_data_changed type g3,
create_dynamic_fcat
importing zogt type struc1
exporting it_fldcat type lvc_t_fcat.
Protected section.
data: stab type ref to data,
wa_it_fldcat type lvc_s_fcat,
c_index type sy-index.
endclass.
class zcltest implementation.
METHOD constructor.
CALL METHOD super->constructor
EXPORTING
i_appl_events = 'X'
i_parent = i_parent.
endmethod.
method disp_tab.
mt_outtab is the data table held as a protected
attribute in class cl_gui_alv_grid.
assign me->mt_outtab->* TO <outtab>. "Original data
assign p_er_data_changed->mp_mod_rows TO <FS1>.
stab = p_er_data_changed->mp_mod_rows.
assign p_er_data_changed->mt_inserted_rows to <fs3>.
assign p_er_data_changed->mt_deleted_rows to <fs4>.
assign p_er_data_changed->mt_mod_cells to <fs5>.
assign stab->* TO <fs2>.
do whatever you want with <outtab>
contains data BEFORE changes each time.
*
Note that NEW (Changed) table has been obtained
already by call to form
check_data USING P_ER_DATA_CHANGED
TYPE REF TO CL_ALV_CHANGED_DATA_PROTOCOL.
Entered data is in table defined by <fs2>
In this method you can compare original and changed data.
*
Easier than messing around with individual cells.
do what you want with data in <fs2> validate / update / merge etc
*
endmethod.
method create_dynamic_fcat.
loop at zogt into zog.
c_index = c_index + 1.
clear wa_it_fldcat.
wa_it_fldcat-fieldname = zog-name .
wa_it_fldcat-datatype = zog-type_kind.
wa_it_fldcat-inttype = zog-type_kind.
wa_it_fldcat-intlen = zog-length.
wa_it_fldcat-decimals = zog-decimals.
wa_it_fldcat-coltext = zog-name.
wa_it_fldcat-lowercase = 'X'.
if c_index eq 2.
wa_it_fldcat-emphasize = 'C411'.
endif.
if c_index eq 3.
wa_it_fldcat-emphasize = 'C511'.
endif.
append wa_it_fldcat to it_fldcat .
endloop.
endmethod. "create_dynamic_fcat
endclass. "zcltest IMPLEMENTATION
class lcl_grid_event_receiver definition.
public section.
note that zcltest inherits all of events etc from
class cl_gui_alv_grid so specify event handler for
zcltest.
methods:
handle_data_changed
for event data_changed of zcltest
importing er_data_changed,
toolbar
for event toolbar of zcltest
importing e_object
e_interactive,
user_command
for event user_command of zcltest
importing e_ucomm.
endclass.
class lcl_grid_event_receiver implementation.
method handle_data_changed.
code whatever required after data entry.
various possibilites here as you
can get back Cell(s) changed
columns or the entire updated table.
Data validation is also possible here.
Note here the field sybol <g2> contains our
instance of class zcltest so we can now
call any methods / access
attributes of that class from this method
in our event handler class.
call method <g2>->disp_tab
EXPORTING
p_er_data_changed = er_data_changed.
endmethod. "handle_data_changed
method toolbar.
data : ls_toolbar type stb_button.
clear ls_toolbar.
move 0 to ls_toolbar-butn_type.
move 'EDIT' to ls_toolbar-function.
move space to ls_toolbar-disabled.
move 'Edit' to ls_toolbar-text.
move icon_change_text to ls_toolbar-icon.
move 'Click2Edit' to ls_toolbar-quickinfo.
append ls_toolbar to e_object->mt_toolbar.
clear ls_toolbar.
move 0 to ls_toolbar-butn_type.
move 'UPDA' to ls_toolbar-function.
move space to ls_toolbar-disabled.
move 'Update' to ls_toolbar-text.
move icon_system_save to ls_toolbar-icon.
move 'Click2Update' to ls_toolbar-quickinfo.
append ls_toolbar to e_object->mt_toolbar.
clear ls_toolbar.
move 0 to ls_toolbar-butn_type.
move 'EXIT' to ls_toolbar-function.
move space to ls_toolbar-disabled.
move 'Exit' to ls_toolbar-text.
move icon_system_end to ls_toolbar-icon.
move 'Click2Exit' to ls_toolbar-quickinfo.
append ls_toolbar to e_object->mt_toolbar.
endmethod. "toolbar
method user_command.
case e_ucomm .
when 'EDIT'. "From Tool bar
perform set_input.
perform init_grid.
when 'UPDA'. "From Tool bar
perform refresh_disp.
perform update_table.
when 'EXIT'. "From Tool bar
leave program.
endcase.
endmethod. "user_command
endclass. "lcl_grid_event_receiver IMPLEMENTATION
program data
*
include <icon>.
define any old internal structure NOT in DDIC
types: begin of s_elements,
anyfield1(20) type c,
anyfield2(20) type c,
anyfield3(20) type c,
anyfield4(20) type c,
anyfield5(11) type n,
end of s_elements.
data: wa_element type s_elements,
wa_data type s_elements.
Note new RTTI functionality allows field detail
retrieval at runtime for dynamic tables.
data:
grid1 type ref to zcltest,
grid_handler type ref to lcl_grid_event_receiver,
c_dec2 type s_elements-anyfield5,
wa_it_fldcat type lvc_s_fcat,
it_fldcat type lvc_t_fcat,
lr_rtti_struc TYPE REF TO cl_abap_structdescr, "RTTI
lt_comp TYPE cl_abap_structdescr=>component_table,"RTTI
ls_comp LIKE LINE OF lt_comp, "RTTI
zog like line of lr_rtti_struc->components, "RTTI
struct_grid_lset type lvc_s_layo,
l_valid type c,
new_table type ref to data.
types: struc like zog.
data: zogt type table of struc,
grid_container1 type ref to cl_gui_custom_container,
g_event_receiver type ref to lcl_grid_event_receiver,
ok_code like sy-ucomm,
i4 type int4.
start-of-selection.
call screen 100.
module status_0100 output.
if grid_container1 is initial.
create object grid_container1
exporting
container_name = 'CCONTAINER1'.
assign grid_container1 to <g1>.
create object grid1
exporting i_parent = grid_container1.
we need reference to this instance so we can use
Methods etc of zcltest class and alv (superclass)
in our event receiver class.
assign grid1 to <g2>.
create object grid_handler.
set handler:
grid_handler->user_command for grid1,
grid_handler->toolbar for grid1,
grid_handler->handle_data_changed for grid1.
Get the Internal table structure
lr_rtti_struc ?= cl_abap_structdescr=>describe_by_data( wa_data ).
Build field catalog just use basic data here
colour specific columns as well
zogt[] = lr_rtti_struc->components.
call method grid1->create_dynamic_fcat
EXPORTING
zogt = zogt
IMPORTING
it_fldcat = it_fldcat.
Create dynamic internal table and assign
to field symbol.
Use dynamic field catalog just built.
call method cl_alv_table_create=>create_dynamic_table
EXPORTING
it_fieldcatalog = it_fldcat
IMPORTING
ep_table = new_table.
assign new_table->* to <dyn_table>.
perform populate_dynamic_itab.
perform init_grid.
perform register_enter_event.
set off ready for input initially
i4 = 0.
call method grid1->set_ready_for_input
EXPORTING
i_ready_for_input = i4.
endif.
endmodule. "status_0100 OUTPUT
module user_command_0100 input.
*
*PAI not needed in OO ALV anymore as User Commands
are handled as events
*in method user_command.
*
we can also get control if any data was entered
and the ENTER is pressed by
raising an event.
Control then returns to method handle_data_changed.
endmodule. "user_command_0100 INPUT
form populate_dynamic_itab.
load up a line of the dynamic table
c_dec2 = c_dec2 + 11.
wa_element-anyfield1 = 'Tabbies'.
wa_element-anyfield2 = 'ger.shepards'.
wa_element-anyfield3 = 'White mice'.
wa_element-anyfield4 = 'Any old text'.
wa_element-anyfield5 = c_dec2.
append wa_element to <dyn_table>.
endform. "populate_dynamic_itab
form exit_program.
call method grid_container1->free.
call method cl_gui_cfw=>flush.
leave program.
endform. "exit_program
form refresh_disp.
call method grid1->refresh_table_display.
endform. "refresh_disp
form update_table.
The dynamic table here is the changed table
read from the grid
after user has changed it
Data can be saved to DB or whatever.
loop at <dyn_table> into wa_element.
do what you want with the data here
*
endloop.
switch off edit mode again for next function
i4 = 0.
call method grid1->set_ready_for_input
EXPORTING
i_ready_for_input = i4.
endform. "update_table
form set_input.
i4 = 1.
call method grid1->set_ready_for_input
EXPORTING
i_ready_for_input = i4.
endform. "set_input
form switch_input.
if i4 = 1.
i4 = 0.
else.
i4 = 1.
endif.
call method grid1->set_ready_for_input
EXPORTING
i_ready_for_input = i4.
endform. "switch_input
form init_grid.
Enabling the grid to edit mode,
struct_grid_lset-edit = 'X'. "To enable editing in ALV
struct_grid_lset-grid_title = 'Jimbos Test'.
call method grid1->set_table_for_first_display
EXPORTING
is_layout = struct_grid_lset
CHANGING
it_outtab = <dyn_table>
it_fieldcatalog = it_fldcat.
endform. "init_grid
form register_enter_event.
call method grid1->register_edit_event
EXPORTING
i_event_id = cl_gui_alv_grid=>mc_evt_enter.
Instantiate the event or it won't work.
create object g_event_receiver.
set handler g_event_receiver->handle_data_changed for grid1.
endform. "register_enter_event
Have fun with this
Cheers
jimbo