Total and subtotals problem in Export Excel from ALV tree - abap

I have created a SALV tree, using the CL_SALV_TREE class, the output is shown in the following image:
Now for the export in Excel that works correctly for me, I have used the following code, but the problem is that it does not export the subtotals, so how could I add the subtotals or how could I solve it? since apparently the aggregation functions can't be visible in the ALV tree.
CLASS lcl_tree IMPLEMENTATION.
METHOD export_tree.
DATA: lr_data TYPE REF TO data,
lt_spfli TYPE STANDARD TABLE OF spfli,
levels TYPE TABLE OF rsplf_srv_p.
DATA: lr_zip TYPE REF TO cl_abap_zip,
lr_xlnode TYPE REF TO if_ixml_node,
lr_xldimension TYPE REF TO if_ixml_node,
lr_file TYPE REF TO cl_xml_document,
lr_xlrows TYPE REF TO if_ixml_node_list,
lr_xlrow TYPE REF TO if_ixml_element,
lr_xlformat TYPE REF TO if_ixml_element,
lr_xlworksheet TYPE REF TO if_ixml_element.
FIELD-SYMBOLS: <spfli> TYPE spfli.
DATA(lt_nodes) = go_alv_tree->get_nodes( )->get_all_nodes( ).
LOOP AT lt_nodes INTO DATA(ls_node).
DATA(lr_node) = ls_node-node.
DATA(lv_level) = 0.
DO.
TRY.
lr_node = lr_node->get_parent( ).
lv_level = lv_level + 1.
CATCH cx_salv_msg.
EXIT.
ENDTRY.
ENDDO.
APPEND VALUE rsplf_srv_p( indx = sy-tabix value = lv_level ) TO levels.
lr_data = ls_node-node->get_data_row( ).
ASSIGN lr_data->* TO <spfli>.
APPEND <spfli> TO lt_spfli.
ENDLOOP.
cl_salv_table=>factory(
IMPORTING
r_salv_table = DATA(lr_table)
CHANGING
t_table = lt_spfli ).
DATA(lv_xlsx) = lr_table->to_xml( if_salv_bs_xml=>c_type_xlsx ).
CREATE OBJECT lr_zip.
lr_zip->load( lv_xlsx ).
lr_zip->get( EXPORTING name = 'xl/worksheets/sheet1.xml' IMPORTING
content = DATA(lv_file) ).
CREATE OBJECT lr_file.
lr_file->parse_xstring( lv_file ).
* Row elements are under SheetData
lr_xlnode = lr_file->find_node( 'sheetData' ).
lr_xlrows = lr_xlnode->get_children( ).
DO lr_xlrows->get_length( ) TIMES.
lr_xlrow ?= lr_xlrows->get_item( sy-index - 1 ).
READ TABLE lt_nodes INTO ls_node INDEX sy-index - 1. "find this row
in tree
IF sy-subrc = 0.
READ TABLE levels ASSIGNING FIELD-SYMBOL(<line_level>) INDEX sy-index.
* Find the level of the node
CHECK <line_level>-value - 1 NE 0.
* Assign the level to row
lr_xlrow->set_attribute( name = 'outlineLevel' value = condense( CONV string( <line_level>-value - 1 ) ) ).
lr_xlrow->set_attribute( name = 'hidden' value = 'true' ).
ENDIF.
ENDDO.
* Create new element in the XML file
lr_xlworksheet ?= lr_file->find_node( 'worksheet' ).
DATA(lr_xlsheetpr) = cl_ixml=>create( )->create_document( )->create_element( name = 'sheetPr' ).
DATA(lr_xloutlinepr) = cl_ixml=>create( )->create_document( )->create_element( name = 'outlinePr' ).
lr_xlsheetpr->if_ixml_node~append_child( lr_xloutlinepr ).
lr_xloutlinepr->set_attribute( name = 'summaryBelow' value = 'false' ).
lr_xldimension ?= lr_file->find_node( 'dimension' ).
lr_xlworksheet->if_ixml_node~insert_child( new_child = lr_xlsheetpr ref_child = lr_xldimension ).
* Create xstring and move it to XLSX
lr_file->render_2_xstring( IMPORTING stream = lv_file ).
lr_zip->delete( EXPORTING name = 'xl/worksheets/sheet1.xml' ).
lr_zip->add( EXPORTING name = 'xl/worksheets/sheet1.xml' content = lv_file ).
lv_xlsx = lr_zip->save( ).
DATA lv_size TYPE i.
DATA lt_bintab TYPE solix_tab.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_xlsx
IMPORTING
output_length = lv_size
TABLES
binary_tab = lt_bintab.
CHECK lt_bintab IS NOT INITIAL.
DATA(p_file) = cl_openxml_helper=>browse_local_file_open( iv_title = 'Save to XLSX File' iv_filename = '' iv_extpattern = 'All files(*.*)|*.*' ).
cl_gui_frontend_services=>gui_download( EXPORTING bin_filesize = lv_size
filename = p_file && `.xlsx`
filetype = 'BIN'
CHANGING data_tab = lt_bintab ).
ENDMETHOD.
ENDCLASS.
I tried to replicate the code from this link: https://blogs.sap.com/2015/07/24/salv-tree-to-excel-xlsx/comment-page-1/#comment-658453
There, what it does is add this add-corresponding statement before adding it to the ALV, but that doesn't work on classes which I'm using in my program:
"ADD-CORRESPONDING" is not supported in the OO context

If your question is simplified to what is the code equivalent to add-corresponding in the "OO context", this is one possible answer, I propose the method add_corresponding below, and a test code to demonstrate how it works - this code compiles in 7.40 SP08:
CLASS lcx_add_corresp_not_all_struct DEFINITION INHERITING FROM cx_static_check.
ENDCLASS.
CLASS lcl_app DEFINITION.
PUBLIC SECTION.
CLASS-METHODS add_corresponding IMPORTING from_struct TYPE any
CHANGING to_struct TYPE any
RAISING lcx_add_corresp_not_all_struct
cx_sy_conversion_overflow.
ENDCLASS.
CLASS lcl_app IMPLEMENTATION.
METHOD add_corresponding.
TYPES: ty_names TYPE HASHED TABLE OF abap_compname WITH UNIQUE KEY table_line,
ty_names_in_structs TYPE STANDARD TABLE OF ty_names WITH EMPTY KEY,
ty_table_rtti TYPE STANDARD TABLE OF REF TO cl_abap_typedescr WITH EMPTY KEY.
DATA(rtti_from_struct) = cl_abap_typedescr=>describe_by_data( from_struct ).
DATA(rtti_to_struct) = cl_abap_typedescr=>describe_by_data( to_struct ).
IF rtti_from_struct->kind <> rtti_from_struct->kind_struct
OR rtti_to_struct->kind <> rtti_to_struct->kind_struct.
RAISE EXCEPTION NEW lcx_add_corresp_not_all_struct( ).
ENDIF.
DATA(names_in_structs) = VALUE ty_names_in_structs(
FOR rtti IN VALUE ty_table_rtti( ( rtti_from_struct ) ( rtti_to_struct ) )
( VALUE #( FOR <comp> IN CAST cl_abap_structdescr( rtti )->components
WHERE ( type_kind CA '8abeFIPs' ) " all numeric types
( <comp>-name ) ) ) ).
DATA(same_names) = FILTER ty_names( names_in_structs[ 1 ] IN names_in_structs[ 2 ] WHERE table_line = table_line ).
LOOP AT same_names REFERENCE INTO DATA(same_name).
ASSIGN COMPONENT same_name->* OF STRUCTURE from_struct TO FIELD-SYMBOL(<from_number>).
ASSERT sy-subrc = 0.
ASSIGN COMPONENT same_name->* OF STRUCTURE to_struct TO FIELD-SYMBOL(<to_number>).
ASSERT sy-subrc = 0.
<to_number> = <to_number> + <from_number>.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
CLASS ltc_app DEFINITION
FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS test FOR TESTING RAISING cx_static_check.
METHODS overflow FOR TESTING RAISING cx_static_check.
ENDCLASS.
CLASS ltc_app IMPLEMENTATION.
METHOD test.
TYPES: ty_output LIKE ls_output.
ls_output = VALUE #( clabs = 100 ceinm = 500 ).
DATA(ls_output2) = ls_output.
lcl_app=>add_corresponding( EXPORTING from_struct = ls_output2 CHANGING to_struct = ls_output ).
cl_abap_unit_assert=>assert_equals( act = ls_output exp = VALUE ty_output( clabs = 200 ceinm = 1000 ) ).
ENDMETHOD.
METHOD overflow.
TYPES: BEGIN OF ty_struct,
int1 TYPE int1,
END OF ty_struct.
DATA(from_struct) = VALUE ty_struct( int1 = 200 ).
DATA(to_struct) = from_struct.
TRY.
lcl_app=>add_corresponding( EXPORTING from_struct = from_struct CHANGING to_struct = to_struct ).
CATCH cx_sy_conversion_overflow INTO DATA(arithmetic_overflow).
ENDTRY.
cl_abap_unit_assert=>assert_bound( act = arithmetic_overflow msg = |Actual: { to_struct-int1 } ; expected: arithmetic overflow| ).
ENDMETHOD.
ENDCLASS.
NB: instead of ADD-CORRESPONDING, you may simply use ls_output-clabs = ls_output-clabs + ls_mchb-clabs and repeat for all numeric components.
NB: ADD-CORRESPONDING and other arithmetic "corresponding" statements were made obsolete because they are considered error-prone:
"These statements are error-prone because, particularly in complex structures, it is not easy to check that identically named components have the data type and content necessary for a numeric operation."

Related

How can I use dynamic SALV with 3 different raditobutton in OO ABAP

I have to do Batch program for 3 different info types (0014,0015,2010).
First step, I have a parameter that is reading the .xls file in a selection screen and 3 different radio buttons for each info type. I want to display a different ALV as when I execute the program with selected radio button. For example, I want to see 0014 if I selected 0014's radio button. The same situation for others.
I can do what I want with one way. That's way is using Perform which have parameters tables and using.
But I cannot do it with OO ABAP. It means using SALV and CLASS/Method style.
Anyone can guide me?
*------------DEFINITION--------
class lcl_report definition.
public section.
types: begin of ty_list_14,
pernr(8) type c,
begda(10) type c,
endda(10) type c,
lgart(5) type c,
betrg(9) type c,
anzhl type i,
message(200) type c,
durum(5) type c,
end of ty_list_14.
data: gt_list_14 type standard table of ty_list_14,
gs_list_14 like line of gt_list_14.
methods:
check_filename,
file_operations,
display_alv.
private section.
data: mo_alv type ref to cl_salv_table.
data: gt_rows type salv_t_row,
gs_rows type i.
data: it_raw type truxs_t_text_data.
data: v_strln type i,
offset type i,
extension type string.
data: i_0014 type table of p0014 initial size 1,
w_0014 type p0014,
l_bapireturn type bapireturn1.
data: filename type string.
methods:
create_alv,
selection_rows,
alv_properties,
upload_file,
create_record_i0014.
methods :
on_user_command for event added_function of cl_salv_events
importing e_salv_function.
endclass.
*------------IMPLEMENTATION--------
class lcl_report implementation.
method display_alv.
me->create_alv( ).
me->selection_rows( ).
me->alv_properties( ).
endmethod.
method file_operations.
me->upload_file( ).
endmethod.
method create_alv.
data: lo_events type ref to cl_salv_events_table.
try.
cl_salv_table=>factory(
importing
r_salv_table = mo_alv
changing
t_table = gt_list_14[]
).
catch cx_salv_msg.
endtry.
lo_events = mo_alv->get_event( ).
set handler go_report->on_user_command for lo_events.
mo_alv->display( ).
endmethod.
method selection_rows .
data: lo_selection type ref to cl_salv_selections.
try.
"Soldan seçim kutularını ekrana getirir.
lo_selection = mo_alv->get_selections( ).
lo_selection->set_selection_mode( if_salv_c_selection_mode=>row_column ).
catch cx_salv_not_found.
endtry.
endmethod.
method check_filename.
v_strln = strlen( p_file ).
if v_strln le 4.
message text-003 type 'E'.
else.
offset = v_strln - 1.
do v_strln times.
if p_file+offset(1) eq '.'.
extension = p_file+offset.
shift extension left deleting leading '.'.
exit.
endif.
subtract 1 from offset.
enddo.
if extension ne 'xls' and
extension ne 'XLS' and
extension ne 'xlsx' and
extension ne 'XLSX' and
extension ne 'txt' and
extension ne 'TXT'.
message text-003 type 'E'.
endif.
endif.
endmethod.
method create_record_i0014.
data: lv_begda type begda,
lv_endda type endda.
loop at gt_rows into gs_rows.
read table gt_list_14 into gs_list_14 index gs_rows.
call function 'CONVERSION_EXIT_ALPHA_INPUT'
exporting
input = gs_list_14-pernr
importing
output = gs_list_14-pernr.
call function 'CONVERSION_EXIT_QNTY1_INPUT'
exporting
input = gs_list_14-betrg
importing
output = gs_list_14-betrg.
clear: lv_begda, lv_endda.
concatenate gs_list_14-begda+6(4)
gs_list_14-begda+3(2)
gs_list_14-begda(2)
into lv_begda.
concatenate gs_list_14-endda+6(4)
gs_list_14-endda+3(2)
gs_list_14-endda(2)
into lv_endda.
move-corresponding gs_list_14 to w_0014.
w_0014-infty = '0014'.
w_0014-begda = lv_begda.
w_0014-endda = lv_endda.
w_0014-lgart = gs_list_14-lgart.
w_0014-betrg = gs_list_14-betrg.
w_0014-anzhl = gs_list_14-anzhl.
append w_0014 to i_0014.
call function 'BAPI_EMPLOYEE_ENQUEUE'
exporting
number = w_0014-pernr
importing
return = l_bapireturn.
call function 'HR_INFOTYPE_OPERATION'
exporting
infty = '0014'
number = w_0014-pernr
record = w_0014
operation = 'INS'
importing
return = l_bapireturn.
gs_list_14-message = l_bapireturn-message.
if l_bapireturn-type eq 'E'.
gs_list_14-durum = '#5C#'.
elseif l_bapireturn-type eq 'W'.
gs_list_14-durum = '#5D#'.
elseif l_bapireturn-type eq 'S' or
l_bapireturn-type is initial.
gs_list_14-durum = '#5B#'.
gs_list_14-message = text-033.
endif.
call function 'BAPI_EMPLOYEE_DEQUEUE'
exporting
number = w_0014-pernr
importing
return = l_bapireturn.
modify gt_list_14 from gs_list_14 index gs_rows.
clear: gs_list_14, w_0014.
refresh i_0014.
endloop.
endmethod.
method on_user_command.
data: lo_selection type ref to cl_salv_selections.
lo_selection = mo_alv->get_selections( ).
gt_rows = lo_selection->get_selected_rows( ).
case e_salv_function.
when '&AKTAR'.
me->create_record_i0014( ).
endcase.
mo_alv->refresh( ).
endmethod.
endclass.
You need create a field-symbol like Excel table structure and set this field-symbol in the SALV.
See this post to know how to create the field-symbol.
Create a structure from a dynamically assigned <itab>
Best regards.
Sebastian

ALV Grid custom F4 help works but then shows No help found

I have a program that displays an editable ALV grid, with a custom F4 help for the field "No." handled via the event onf4. My custom F4 help is displayed and the selected value is returned correctly.
However every time after the custom F4 help closes, another window opens saying "No input help is available".
How to get rid of this supplementary popup?
Thanks.
Here's my code:
CLASS lcl_app DEFINITION.
PUBLIC SECTION.
METHODS constructor.
METHODS display.
METHODS on_onf4
FOR EVENT onf4 OF cl_gui_alv_grid
IMPORTING e_fieldname es_row_no e_fieldvalue.
DATA: grid TYPE REF TO cl_gui_alv_grid,
spflis TYPE TABLE OF spfli.
ENDCLASS.
CLASS lcl_app IMPLEMENTATION.
METHOD constructor.
SELECT * FROM spfli INTO TABLE spflis.
grid = NEW cl_gui_alv_grid(
i_parent = cl_gui_container=>screen0 ).
SET HANDLER on_onf4 FOR grid.
grid->register_f4_for_fields(
it_f4 = VALUE #( ( fieldname = 'CONNID' register = 'X' chngeafter = 'X' ) ) ).
ENDMETHOD.
METHOD display.
DATA(fcat) = VALUE lvc_t_fcat(
( fieldname = 'CARRID' ref_table = 'SPFLI' )
( fieldname = 'CONNID' ref_table = 'SPFLI' f4availabl = 'X' ) ).
grid->set_table_for_first_display(
EXPORTING is_layout = VALUE #( edit = 'X' )
CHANGING it_outtab = spflis
it_fieldcatalog = fcat
EXCEPTIONS OTHERS = 4 ).
ENDMETHOD.
METHOD on_onf4.
DATA return TYPE TABLE OF ddshretval.
IF e_fieldname = 'CONNID'.
SELECT DISTINCT connid FROM spfli INTO TABLE #DATA(connids).
CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
EXPORTING
retfield = 'CONNID'
value_org = 'S'
TABLES
value_tab = connids
return_tab = return
EXCEPTIONS
parameter_error = 1
no_values_found = 2
OTHERS = 3.
IF sy-subrc = 0 AND return IS NOT INITIAL.
FIELD-SYMBOLS <modis> TYPE lvc_t_modi.
ASSIGN er_event_data->m_data->* TO <modis>.
<modis> = VALUE #( BASE <modis> ( row_id = es_row_no-row_id
fieldname = e_fieldname
value = return[ 1 ]-fieldval ) ).
ENDIF.
ENDIF.
ENDMETHOD.
ENDCLASS.
PARAMETERS dummy.
AT SELECTION-SCREEN OUTPUT.
NEW lcl_app( )->display( ).
There's a flag er_event_data->m_event_handled which needs to be set to 'X' in the F4 method handler to say that the F4 was actually managed by the custom handling, otherwise the ALV grid attempts displaying the standard F4 (there was no standard F4 in my case hence the popup).
First add the ER_EVENT_DATA parameter in the method declaration :
METHODS on_onf4
FOR EVENT onf4 OF cl_gui_alv_grid
IMPORTING e_fieldname es_row_no e_fieldvalue
er_event_data.
Inside the method ON_ONF4, set the flag :
er_event_data->m_event_handled = 'X'.

How to display itab in ALV with dynamic layout variant?

I am using the class CL_GUI_ALV_GRID and a dynpro screen to display an internal table via the ALV tool.
In my selection screen I have a dropdown list where the user can choose a layout variant for the displayed internal table. The layout variants are stored in the table LTDX.
Now, back to my question, how can I display the variants depending on the selection of the user?
You supply in the initial set_table_for_first_display method the is_variant parameter:
DATA: ls_variant TYPE disvariant.
CLEAR: ls_variant.
ls_variant-report = sy-repid.
ls_variant-variant = pa_varid. "<<< this is the name of the variant
CALL METHOD gro_alv100->set_table_for_first_display
EXPORTING
is_variant = ls_variant
...
EDIT: okay you did not accept the simple answer, so I will add the manual alternative:
FORM set_variant USING ps_variant TYPE disvariant.
DATA: lf_user_specific TYPE char1,
ls_stable TYPE lvc_s_stbl VALUE 'XX'.
CHECK ps_variant-variant IS NOT INITIAL.
lf_user_specific = boolc( ps_variant-variant(1) <> '/' ).
CALL FUNCTION 'LVC_VARIANT_SELECT'
EXPORTING
i_dialog = space
i_user_specific = lf_user_specific
i_default = space
it_default_fieldcat = gt_fcat
IMPORTING
et_fieldcat = gt_fcat
et_sort = gt_sort
et_filter = gt_filter
TABLES
it_data = gt_outtab
CHANGING
cs_variant = ps_variant
EXCEPTIONS
wrong_input = 1
fc_not_complete = 2
not_found = 3
program_error = 4
data_missing = 5
OTHERS = 6.
IF sy-subrc <> 0.
ENDIF.
gro_alv100->set_variant( EXPORTING is_variant = ps_variant ).
gro_alv100->set_frontend_fieldcatalog( EXPORTING it_fieldcatalog = gt_fcat ).
gro_alv100->set_sort_criteria( EXPORTING it_sort = gt_sort ).
gro_alv100->set_filter_criteria( EXPORTING it_filter = gt_filter ).
gro_alv100->refresh_table_display( EXPORTING is_stable = ls_stable i_soft_refresh = abap_false ).
ENDFORM.

How to disable the Editable ALV Grid in case of an incorrect entry?

Whenever an invalid value is entered in an ALV Grid, how do I disable the other fields (grey out) in the grid and force the user to fix the incorrect field.
I have tried adding protocol in DATA_CHANGED event. But protocol list only shows the error in popup. Editing is still possible and no fields are disabled.
But how do I disable the other fields. Sample behavior as shown below:
Here, the other fields are greyed out and the invalid entry is highlighted. Until the user fixes this error, he/she cannot proceed further.
Having screen 100 with container CCONTAINER1 paste this snippet
CLASS zcl_alv_test DEFINITION.
PUBLIC SECTION.
METHODS: constructor, display_grid, populate_grid.
DATA: lr_rtti_struc TYPE REF TO cl_abap_structdescr,
it_fldcat TYPE lvc_t_fcat,
grid_container1 TYPE REF TO cl_gui_custom_container,
grid1 TYPE REF TO cl_gui_alv_grid.
DATA: BEGIN OF gs_outtab.
INCLUDE TYPE spfli.
DATA: celltab TYPE lvc_t_styl.
DATA: END OF gs_outtab.
DATA gt_outtab1 LIKE TABLE OF gs_outtab INITIAL SIZE 0.
METHODS:
handle_data_changed FOR EVENT data_changed OF cl_gui_alv_grid IMPORTING er_data_changed,
handle_data_changed_finished FOR EVENT data_changed_finished OF cl_gui_alv_grid IMPORTING e_modified et_good_cells,
create_dynamic_fcat.
PRIVATE SECTION.
TYPES: ty_tab LIKE LINE OF gt_outtab1.
METHODS: refresh_grid, fill_celltab IMPORTING p_fieldname TYPE lvc_fname
CHANGING pt_celltab TYPE lvc_t_styl.
ENDCLASS.
CLASS zcl_alv_test IMPLEMENTATION.
METHOD constructor.
CREATE OBJECT grid_container1 EXPORTING container_name = 'CCONTAINER1'.
CREATE OBJECT grid1 EXPORTING i_parent = grid_container1.
SET HANDLER handle_data_changed FOR grid1.
SET HANDLER handle_data_changed_finished FOR grid1.
CALL METHOD grid1->register_edit_event
EXPORTING
i_event_id = cl_gui_alv_grid=>mc_evt_enter.
ENDMETHOD. "constructor
METHOD fill_celltab.
LOOP AT pt_celltab ASSIGNING FIELD-SYMBOL(<fs_fcat>).
IF <fs_fcat>-fieldname = p_fieldname.
<fs_fcat>-style = cl_gui_alv_grid=>mc_style_enabled.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD handle_data_changed.
DATA: lt_celltab TYPE lvc_t_styl.
LOOP AT it_fldcat ASSIGNING FIELD-SYMBOL(<fs_fcat>).
INSERT VALUE lvc_s_styl( style = cl_gui_alv_grid=>mc_style_disabled fieldname = <fs_fcat>-fieldname ) INTO TABLE lt_celltab.
ENDLOOP.
MODIFY gt_outtab1 FROM VALUE ty_tab( celltab = lt_celltab ) TRANSPORTING celltab WHERE connid IS NOT INITIAL.
LOOP AT er_data_changed->mt_mod_cells ASSIGNING FIELD-SYMBOL(<mods>).
READ TABLE gt_outtab1 ASSIGNING FIELD-SYMBOL(<sym>) INDEX <mods>-row_id.
fill_celltab( EXPORTING p_fieldname = <mods>-fieldname
CHANGING pt_celltab = <sym>-celltab ).
MODIFY gt_outtab1 FROM <sym> INDEX <mods>-row_id.
ENDLOOP.
refresh_grid( ).
ENDMETHOD.
METHOD handle_data_changed_finished.
DATA: lt_celltab TYPE lvc_t_styl.
LOOP AT it_fldcat ASSIGNING FIELD-SYMBOL(<fs_fcat>).
IF sy-tabix MOD 2 = 0.
DATA(style) = cl_gui_alv_grid=>mc_style_disabled.
ELSE.
style = cl_gui_alv_grid=>mc_style_enabled.
ENDIF.
INSERT VALUE lvc_s_styl( style = style fieldname = <fs_fcat>-fieldname ) INTO TABLE lt_celltab.
ENDLOOP.
MODIFY gt_outtab1 FROM VALUE ty_tab( celltab = lt_celltab ) TRANSPORTING celltab WHERE connid IS NOT INITIAL.
refresh_grid( ).
ENDMETHOD.
METHOD create_dynamic_fcat.
lr_rtti_struc ?= cl_abap_structdescr=>describe_by_name( 'SPFLI' ).
DATA(comps) = lr_rtti_struc->components.
LOOP AT comps ASSIGNING FIELD-SYMBOL(<comps>).
IF sy-tabix MOD 2 = 0.
DATA(edit) = abap_false.
ELSE.
edit = abap_true.
ENDIF.
APPEND VALUE lvc_s_fcat( edit = edit fieldname = <comps>-name datatype = <comps>-type_kind inttype = <comps>-type_kind intlen = <comps>-length decimals = <comps>-decimals coltext = <comps>-name lowercase = 'X' ) TO it_fldcat .
ENDLOOP.
ENDMETHOD. "create_dynamic_fcat
METHOD populate_grid.
SELECT * UP TO 1000 ROWS
FROM spfli
INTO CORRESPONDING FIELDS OF TABLE gt_outtab1.
ENDMETHOD. "CHANGE_TITLE
METHOD display_grid.
create_dynamic_fcat( ).
grid1->set_table_for_first_display(
EXPORTING
is_layout = VALUE lvc_s_layo( zebra = abap_true stylefname = 'CELLTAB' )
CHANGING
it_outtab = gt_outtab1
it_fieldcatalog = it_fldcat ).
ENDMETHOD. "display_grid
METHOD refresh_grid.
cl_gui_cfw=>flush( ).
grid1->refresh_table_display( ).
ENDMETHOD.
ENDCLASS.
MODULE status_0100 OUTPUT.
SET PF-STATUS 'MAIN100'.
DATA: yalv TYPE REF TO zcl_alv_test.
CREATE OBJECT yalv.
yalv->populate_grid( ).
yalv->display_grid( ).
ENDMODULE.
MODULE user_command_0100 INPUT.
CASE sy-ucomm.
WHEN 'BACK' OR 'EXIT' OR 'RETURN'.
LEAVE PROGRAM.
WHEN OTHERS.
ENDCASE.
ENDMODULE.
START-OF-SELECTION.
CALL SCREEN 100.
It uses the concept of cell styles, where each row in table is assigned a table of styles for each of the column in this row. There you can apply conditional attributes on a cell level, including editability.
When throwing an error through builtin checktables/domains, the grid is made not editable except erroneous cell, and when correcting the error, editability returns.

How to display list of attachments from Generic Object Services

I have a report that should display an attachment list from an object.
For instance, in transaction FI02 (maintenance of banks), the GOS toolbar has the menu Attachment List:
I want to display this list. What is the best way to display it?
REPORT zay_gos_demo.
DATA ls_appl_object TYPE gos_s_obj.
DATA lo_gos_api TYPE REF TO cl_gos_api.
DATA lt_attachment_list TYPE gos_t_atta.
DATA lt_role_filter TYPE gos_t_rol.
DATA ls_attachment TYPE gos_s_atta.
DATA ls_attachm_cont TYPE gos_s_attcont.
DATA ls_atta_key TYPE gos_s_attkey.
ls_appl_object-typeid = 'KNA1'.
ls_appl_object-instid = '0000000001'.
ls_appl_object-catid = 'BO'. "BO - BOR Object
"CL - Persistent Class
START-OF-SELECTION.
* create instance of GOS API providing unique application object
TRY.
lo_gos_api = cl_gos_api=>create_instance( ls_appl_object ).
* get attachment list for this object (if needed restrict selection
* by adding certain roles to filter table; initial table means: get
* attachments in all roles)
APPEND cl_gos_api=>c_attachment TO lt_role_filter.
APPEND cl_gos_api=>c_annotation TO lt_role_filter.
APPEND cl_gos_api=>c_website TO lt_role_filter.
lt_attachment_list = lo_gos_api->get_atta_list( lt_role_filter ).
CATCH cx_gos_api.
* error handling
ENDTRY.
I found other example and I want to test it:
REPORT zay_attachment_list_display.
DATA: go_attachments TYPE REF TO cl_gos_attachments,
g_att_container TYPE REF TO cl_gui_custom_container,
ls_object TYPE borident,
lo_bitem TYPE REF TO cl_sobl_bor_item.
ls_object-objtype = 'KNA1'.
ls_object-objkey = '0000000001'.
IF NOT go_attachments IS INITIAL.
CLEAR go_attachments.
ENDIF.
CREATE OBJECT g_att_container
EXPORTING
container_name = 'ATTS'
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5.
IF sy-subrc NE 0.
* ADD your handling
ENDIF.
CREATE OBJECT lo_bitem
EXPORTING
is_bor = ls_object.
IF go_attachments IS INITIAL.
CREATE OBJECT go_attachments
EXPORTING
io_object = lo_bitem
ip_check_arl = 'X'
ip_check_bds = 'X'
io_container = g_att_container
* is_layout = ls_layout
* ip_mode = wf_mode
ip_notes = 'X'
ip_attachments = 'X'
ip_urls = 'X'.
ELSE.
go_attachments->set_container( g_att_container ).
ENDIF.
go_attachments->display( ).
I created a custom control in dynpro 0100 and I named it ATTS. I still can't get the attachment list of GOS. Did I miss something?
After weeks of searching and asking. it was really simple. just call the function GOS_ATTACHMENT_LIST_POPUP.
Example:
DATA: ls_object TYPE sibflporb,
save_request TYPE sgs_flag.
ls_object-instid = 'FR 1234567890'.
ls_object-typeid = 'BUS1011'.
ls_object-catid = 'BO'.
CALL FUNCTION 'GOS_ATTACHMENT_LIST_POPUP'
EXPORTING
is_object = ls_object
ip_mode = 'E' " Edit mode
IMPORTING
ep_save_request = save_request.
IF save_request = 'X'.
COMMIT WORK.
ENDIF.