I have an ALV tree and basically what I need to do is to slide (drag) a specific node to the top or bottom or a specific location in the ALV tree.
How could this be accomplished?
For example, here I would like to slide the IF node in place before the AFFECTATIONS node:
Expected node's arrangement:
TL;DR: cl_gui_alv_tree cannot do it like you want it to do it.
Due to the specifics of drag-n-drop implementation in ALV Control Framework, the node in a tree can be either draggable (source) or droppable (target), not both. So dragging a node to another node's place on the same level of hierarchy is not possible, hence it is also not possible to (inter)change nodes with its siblings in runtime.
However, I wanna propose you a helpful piece of code, which shows how one can achieve smth close to the question by dragging the node onto the parent level of hierarchy.
Steps for implementing DND functionality in SAP ALV Framework:
Create event class where handlers of ondrag and ondrop events are implemented.
Create DND storage object lcl_dragdropobj, an empty class through the which you pass grid objects (leaves, nodes) in memory.
Create behavior definition for both source and target objects.
With the help of the above behavior object, assign layout to each node/leaf via is_node_layout parameter. That layout would define node behavior: either it's draggable or droppable.
Here is the sample code, built on spfli/sflight database:
REPORT zyyz.
DATA: g_alv_tree TYPE REF TO cl_gui_alv_tree,
g_custom_container TYPE REF TO cl_gui_custom_container,
g_drag_behaviour TYPE REF TO cl_dragdrop,
g_drop_behaviour TYPE REF TO cl_dragdrop.
DATA: gt_sflight TYPE TABLE OF sflight INITIAL SIZE 0, "Output-Table
gt_fieldcatalog TYPE lvc_t_fcat,
g_top_key TYPE lvc_nkey,
ok_code LIKE sy-ucomm,
save_ok LIKE sy-ucomm, "OK-Code
g_max TYPE i VALUE 255.
CLASS lcl_dragdropobj DEFINITION.
PUBLIC SECTION.
DATA: cp_sflight_root TYPE sflight,
cp_sflights TYPE TABLE OF sflight,
cp_node_text_root TYPE lvc_value,
cp_node_texts TYPE salv_t_value,
lt_selected_carrids TYPE lvc_t_nkey,
lt_selected_leafs TYPE lvc_t_nkey.
ENDCLASS.
CLASS lcl_event_receiver DEFINITION.
PUBLIC SECTION. .
METHODS:
on_drag
FOR EVENT on_drag
OF cl_gui_alv_tree
IMPORTING sender node_key drag_drop_object,
on_drop
FOR EVENT on_drop
OF cl_gui_alv_tree
IMPORTING drag_drop_object.
ENDCLASS.
*---------------------------------------------------------------------*
* CLASS lcl_toolbar_event_receiver IMPLEMENTATION
*---------------------------------------------------------------------*
CLASS lcl_event_receiver IMPLEMENTATION.
METHOD on_drag.
DATA: dataobj TYPE REF TO lcl_dragdropobj,
l_sflight TYPE sflight,
l_node_text TYPE lvc_value.
* create and fill dataobject for event ON_DROP.
CREATE OBJECT dataobj.
* Get dragged month
CALL METHOD sender->get_outtab_line
EXPORTING
i_node_key = node_key
IMPORTING
e_outtab_line = dataobj->cp_sflight_root
e_node_text = dataobj->cp_node_text_root.
CALL METHOD g_alv_tree->get_children
EXPORTING
i_node_key = node_key
IMPORTING
et_children = dataobj->lt_selected_carrids.
LOOP AT dataobj->lt_selected_carrids ASSIGNING FIELD-SYMBOL(<carrid>).
CLEAR: l_sflight, l_node_text.
CALL METHOD sender->get_outtab_line
EXPORTING
i_node_key = <carrid>
IMPORTING
e_outtab_line = l_sflight
e_node_text = l_node_text.
APPEND l_node_text TO dataobj->cp_node_texts.
CALL METHOD g_alv_tree->get_children
EXPORTING
i_node_key = <carrid>
IMPORTING
et_children = dataobj->lt_selected_leafs.
LOOP AT dataobj->lt_selected_leafs ASSIGNING FIELD-SYMBOL(<node>).
CLEAR: l_sflight, l_node_text.
CALL METHOD sender->get_outtab_line
EXPORTING
i_node_key = <node>
IMPORTING
e_outtab_line = l_sflight
e_node_text = l_node_text.
APPEND l_sflight TO dataobj->cp_sflights.
ENDLOOP.
ENDLOOP.
drag_drop_object->object = dataobj.
ENDMETHOD.
METHOD on_drop.
DATA: dataobj TYPE REF TO lcl_dragdropobj,
l_root_key TYPE lvc_nkey,
l_carrid_key TYPE lvc_nkey,
l_new_key TYPE lvc_nkey,
lt_sflights TYPE TABLE OF sflight.
CATCH SYSTEM-EXCEPTIONS move_cast_error = 1.
dataobj ?= drag_drop_object->object.
PERFORM add_month USING dataobj->cp_node_text_root
g_top_key
cl_gui_column_tree=>relat_first_child
CHANGING l_root_key.
*
LOOP AT dataobj->lt_selected_carrids ASSIGNING FIELD-SYMBOL(<node>).
READ TABLE dataobj->cp_node_texts ASSIGNING FIELD-SYMBOL(<text>) INDEX sy-tabix.
DATA(sflight) = VALUE sflight( carrid = <text> ).
PERFORM add_carrid_line USING sflight
l_root_key
cl_gui_column_tree=>relat_last_child
CHANGING l_carrid_key.
CLEAR lt_sflights.
INSERT LINES OF dataobj->cp_sflights INTO TABLE lt_sflights.
DELETE lt_sflights WHERE carrid NE <text>.
LOOP AT lt_sflights ASSIGNING FIELD-SYMBOL(<flight>).
PERFORM add_complete_line USING <flight>
l_carrid_key
CHANGING l_new_key.
ENDLOOP.
ENDLOOP.
PERFORM delete_node.
ENDCATCH.
IF sy-subrc <> 0.
CALL METHOD drag_drop_object->abort.
ENDIF.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
END-OF-SELECTION.
CALL SCREEN 100.
*&---------------------------------------------------------------------*
*& Module PBO OUTPUT
*&---------------------------------------------------------------------*
MODULE pbo OUTPUT.
SET PF-STATUS 'MAIN100'.
SET TITLEBAR 'MAINTITLE'.
IF g_alv_tree IS INITIAL.
PERFORM init_tree.
CALL METHOD cl_gui_cfw=>flush
EXCEPTIONS
cntl_system_error = 1
cntl_error = 2.
ENDIF.
ENDMODULE. " PBO OUTPUT
*&---------------------------------------------------------------------*
*& Module PAI INPUT
*&---------------------------------------------------------------------*
* process after input
*----------------------------------------------------------------------*
MODULE pai INPUT.
save_ok = ok_code.
CLEAR ok_code.
CASE save_ok.
WHEN 'EXIT' OR 'BACK' OR 'CANC'.
PERFORM exit_program.
WHEN OTHERS.
CALL METHOD cl_gui_cfw=>dispatch.
ENDCASE.
CALL METHOD cl_gui_cfw=>flush.
ENDMODULE. " PAI INPUT
*&---------------------------------------------------------------------*
*& Form init_tree
*&---------------------------------------------------------------------*
FORM init_tree.
* create container for alv-tree
DATA: l_tree_container_name(30) TYPE c.
l_tree_container_name = 'CCONTAINER1'.
CREATE OBJECT g_custom_container
EXPORTING
container_name = l_tree_container_name.
IF sy-subrc <> 0.
MESSAGE x208(00) WITH 'ERROR'(100).
ENDIF.
* create tree control
CREATE OBJECT g_alv_tree
EXPORTING
parent = g_custom_container
node_selection_mode = cl_gui_column_tree=>node_sel_mode_single
item_selection = ' '
no_html_header = 'X'
no_toolbar = ''.
IF sy-subrc <> 0.
MESSAGE x208(00) WITH 'ERROR'. "#EC NOTEXT
ENDIF.
DATA l_hierarchy_header TYPE treev_hhdr.
l_hierarchy_header-width = 35.
PERFORM build_fieldcatalog.
CALL METHOD g_alv_tree->set_table_for_first_display
EXPORTING
is_hierarchy_header = l_hierarchy_header
CHANGING
it_fieldcatalog = gt_fieldcatalog
it_outtab = gt_sflight.
PERFORM define_dnd_behaviour.
PERFORM create_hierarchy.
PERFORM register_events.
CALL METHOD g_alv_tree->update_calculations.
CALL METHOD g_alv_tree->frontend_update.
ENDFORM. " init_tree
FORM register_events.
DATA: lt_events TYPE cntl_simple_events,
l_event_receiver TYPE REF TO lcl_event_receiver.
CALL METHOD g_alv_tree->get_registered_events
IMPORTING
events = lt_events.
CALL METHOD g_alv_tree->set_registered_events
EXPORTING
events = lt_events.
IF sy-subrc <> 0.
MESSAGE x208(00) WITH 'ERROR'. "#EC NOTEXT
ENDIF.
CREATE OBJECT l_event_receiver.
SET HANDLER l_event_receiver->on_drop FOR g_alv_tree.
SET HANDLER l_event_receiver->on_drag FOR g_alv_tree.
ENDFORM. " register_events
*&---------------------------------------------------------------------*
*& Form exit_program
*&---------------------------------------------------------------------*
* free object and leave program
*----------------------------------------------------------------------*
FORM exit_program.
CALL METHOD g_custom_container->free.
LEAVE PROGRAM.
ENDFORM. " exit_program
*--------------------------------------------------------------------
FORM build_fieldcatalog.
CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
EXPORTING
i_structure_name = 'SFLIGHT'
CHANGING
ct_fieldcat = gt_fieldcatalog.
ENDFORM. " build_fieldcatalog
*&---------------------------------------------------------------------*
*& Form create_hierarchy
*&---------------------------------------------------------------------*
FORM create_hierarchy.
DATA: ls_sflight TYPE sflight,
lt_sflight TYPE TABLE OF sflight INITIAL SIZE 0,
l_yyyymm TYPE c LENGTH 8, "year and month of sflight-fldate
l_yyyymm_last(6) TYPE c,
l_carrid LIKE sflight-carrid,
l_carrid_last LIKE sflight-carrid.
DATA: l_month_key TYPE lvc_nkey,
l_carrid_key TYPE lvc_nkey,
l_last_key TYPE lvc_nkey,
l_top_key TYPE lvc_nkey,
l_layout_node TYPE lvc_s_layn.
* Select data
SELECT * FROM sflight INTO TABLE lt_sflight UP TO g_max ROWS.
* sort table according to conceived hierarchy
SORT lt_sflight BY fldate+0(6) carrid fldate+6(2).
PERFORM make_drop CHANGING l_layout_node.
CALL METHOD g_alv_tree->add_node
EXPORTING
i_relat_node_key = ''
i_relationship = cl_gui_column_tree=>relat_last_child
i_node_text = text-050
is_node_layout = l_layout_node
IMPORTING
e_new_node_key = l_top_key.
g_top_key = l_top_key.
LOOP AT lt_sflight INTO ls_sflight.
l_yyyymm = ls_sflight-fldate+0(6).
l_carrid = ls_sflight-carrid.
IF l_yyyymm <> l_yyyymm_last. "on change of l_yyyymm
l_yyyymm_last = l_yyyymm.
* month nodes
PERFORM add_month USING l_yyyymm
l_top_key
cl_gui_column_tree=>relat_last_child
CHANGING l_month_key.
* The month changed, thus, there is no predecessor carrier
CLEAR l_carrid_last.
ENDIF.
* Carrier nodes:
IF l_carrid <> l_carrid_last. "on change of l_carrid
l_carrid_last = l_carrid.
PERFORM add_carrid_line USING ls_sflight
l_month_key
cl_gui_column_tree=>relat_last_child
CHANGING l_carrid_key.
ENDIF.
* Leaf:
PERFORM add_complete_line USING ls_sflight
l_carrid_key
CHANGING l_last_key.
ENDLOOP.
CALL METHOD g_alv_tree->expand_node
EXPORTING
i_node_key = l_top_key.
ENDFORM. " create_hierarchy
*&---------------------------------------------------------------------*
*& Form add_month
*&---------------------------------------------------------------------*
FORM add_month USING p_yyyymm TYPE clike
p_relat_key TYPE lvc_nkey
p_relationship TYPE int4
CHANGING p_node_key TYPE lvc_nkey.
DATA: l_node_text TYPE lvc_value,
ls_sflight TYPE sflight,
l_month TYPE c LENGTH 25,
l_layout_node TYPE lvc_s_layn.
IF p_yyyymm CO ' 0123456789'.
p_yyyymm = p_yyyymm && '01'.
CALL FUNCTION 'CONVERSION_EXIT_LDATE_OUTPUT'
EXPORTING
input = p_yyyymm
IMPORTING
output = l_month.
REPLACE REGEX `(\d\d\.\s)([[:alpha:]]*)(\s\d{4})` IN l_month WITH '$2'.
l_node_text = p_yyyymm(4) && `/` && l_month.
ELSE.
l_node_text = p_yyyymm.
ENDIF.
PERFORM make_drag CHANGING l_layout_node.
* add node
CALL METHOD g_alv_tree->add_node
EXPORTING
i_relat_node_key = p_relat_key
i_relationship = p_relationship
i_node_text = l_node_text
is_outtab_line = ls_sflight
is_node_layout = l_layout_node
IMPORTING
e_new_node_key = p_node_key.
ENDFORM. " add_month
*-----------------------------------------------------------------------
FORM add_carrid_line USING ps_sflight TYPE sflight
p_relat_key TYPE lvc_nkey
p_relationship TYPE int4
CHANGING p_node_key TYPE lvc_nkey.
DATA: l_node_text TYPE lvc_value,
ls_sflight TYPE sflight,
l_layout_node TYPE lvc_s_layn.
l_node_text = ps_sflight-carrid.
CALL METHOD g_alv_tree->add_node
EXPORTING
i_relat_node_key = p_relat_key
i_relationship = p_relationship
i_node_text = l_node_text
is_outtab_line = ls_sflight
is_node_layout = l_layout_node
IMPORTING
e_new_node_key = p_node_key.
ENDFORM. " add_carrid_line
*&---------------------------------------------------------------------*
*& Form add_complete_line
*&---------------------------------------------------------------------*
FORM add_complete_line USING ps_sflight TYPE sflight
p_relat_key TYPE lvc_nkey
CHANGING p_node_key TYPE lvc_nkey.
DATA: l_node_text TYPE lvc_value,
l_layout_node TYPE lvc_s_layn.
WRITE ps_sflight-fldate TO l_node_text MM/DD/YYYY.
CALL METHOD g_alv_tree->add_node
EXPORTING
i_relat_node_key = p_relat_key
i_relationship = cl_gui_column_tree=>relat_last_child
is_outtab_line = ps_sflight
i_node_text = l_node_text
is_node_layout = l_layout_node
IMPORTING
e_new_node_key = p_node_key.
ENDFORM. " add_complete_line
FORM define_dnd_behaviour.
DATA: effect TYPE i.
CREATE OBJECT g_drag_behaviour.
effect = cl_dragdrop=>move.
CALL METHOD g_drag_behaviour->add
EXPORTING
flavor = 'default' "#EC NOTEXT
dragsrc = 'X'
droptarget = ' '
effect = effect.
CREATE OBJECT g_drop_behaviour.
effect = cl_dragdrop=>move.
CALL METHOD g_drop_behaviour->add
EXPORTING
flavor = 'default' "#EC NOTEXT
dragsrc = ' '
droptarget = 'X'
effect = effect.
ENDFORM. " DEFINE_DND_BEHAVIOUR
FORM delete_node.
DATA: lt_selected_nodes TYPE lvc_t_nkey,
l_selected_node TYPE lvc_nkey.
CALL METHOD g_alv_tree->get_selected_nodes
CHANGING
ct_selected_nodes = lt_selected_nodes.
CALL METHOD cl_gui_cfw=>flush.
READ TABLE lt_selected_nodes INTO l_selected_node INDEX 1.
IF sy-subrc EQ 0.
CALL METHOD g_alv_tree->delete_subtree
EXPORTING
i_node_key = l_selected_node.
CALL METHOD g_alv_tree->frontend_update.
ELSE. "sy-subrc EQ 0
MESSAGE i000(0k) WITH 'Please select a node.'(900).
ENDIF.
ENDFORM.
FORM make_drag CHANGING p_layout_node TYPE lvc_s_layn.
DATA l_handle_line TYPE i.
CALL METHOD g_drag_behaviour->get_handle
IMPORTING
handle = l_handle_line.
p_layout_node-dragdropid = l_handle_line.
ENDFORM.
FORM make_drop CHANGING p_layout_node TYPE lvc_s_layn.
DATA l_handle_line TYPE i.
CALL METHOD g_drop_behaviour->get_handle
IMPORTING
handle = l_handle_line.
p_layout_node-dragdropid = l_handle_line.
ENDFORM.
In the above example months are made draggable onto the root Flights node. When they are dragged onto it, the place of the dragged node within hierarchy became first. This is not exactly the behavior you asked, but! Through the set of N draggings you can place any node onto any place within that level of hierarchy.
More useful DND examples can be found via BCALV_TREE_* pattern.
CL_GUI_ALV_TREE implements the classic Control Framework drag & drop feature (cf the concept in the SAP Library).
It allows dropping any node on any other node whatever the level is, except that a node cannot be dropped on itself. This is achieved by giving every node a behavior which allows both the drag and the drop.
Hereafter is the minimal program so that to understand quickly what is required to implement a basic drag & drop action. I don't move the node because it's not specific to drag & drop (use the method MOVE_NODE for instance). The SFLIGHT table must be filled by running the program SAPBC_DATA_GENERATOR. Note: I don't recommend to code it like I did, it's just a demonstration program, instead do it more like #Suncatcher's program.
REPORT.
CLASS lcl_app DEFINITION.
PUBLIC SECTION.
METHODS at_selection_screen_output.
METHODS at_selection_screen_exit.
PRIVATE SECTION.
METHODS on_drag FOR EVENT on_drag OF cl_gui_alv_tree
IMPORTING sender node_key drag_drop_object.
METHODS on_drop FOR EVENT on_drop OF cl_gui_alv_tree
IMPORTING sender node_key drag_drop_object.
DATA: g_alv_tree TYPE REF TO cl_gui_alv_tree,
gt_sflight TYPE TABLE OF sflight,
dragged TYPE sflight.
ENDCLASS.
CLASS lcl_app IMPLEMENTATION.
METHOD at_selection_screen_output.
DATA lt_fieldcatalog TYPE lvc_t_fcat.
IF g_alv_tree IS INITIAL.
g_alv_tree = NEW #( parent = cl_gui_container=>screen0
node_selection_mode = cl_gui_column_tree=>node_sel_mode_single ).
CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
EXPORTING
i_structure_name = 'SFLIGHT'
CHANGING
ct_fieldcat = lt_fieldcatalog.
g_alv_tree->set_table_for_first_display(
EXPORTING is_hierarchy_header = VALUE #( width = 35 )
CHANGING it_fieldcatalog = lt_fieldcatalog
it_outtab = gt_sflight ).
SET HANDLER on_drop FOR g_alv_tree.
SET HANDLER on_drag FOR g_alv_tree.
DATA(dnd_move_source_target) = NEW cl_dragdrop( ).
dnd_move_source_target->add(
flavor = 'SINGLE'
dragsrc = abap_true
droptarget = abap_true
effect = cl_dragdrop=>move ).
dnd_move_source_target->get_handle( IMPORTING handle = DATA(dnd_move_source_target_id) ).
SELECT * FROM sflight INTO TABLE #DATA(lt_sflight).
LOOP AT lt_sflight ASSIGNING FIELD-SYMBOL(<ls_sflight>).
g_alv_tree->add_node(
EXPORTING i_relat_node_key = ''
i_relationship = cl_gui_column_tree=>relat_last_child
i_node_text = |{ <ls_sflight>-carrid }-{ <ls_sflight>-connid }-{ <ls_sflight>-fldate }|
is_outtab_line = <ls_sflight>
is_node_layout = VALUE #( dragdropid = dnd_move_source_target_id ) ).
ENDLOOP.
g_alv_tree->frontend_update( ).
ENDIF.
ENDMETHOD.
METHOD at_selection_screen_exit.
cl_gui_container=>screen0->free( ).
ENDMETHOD.
METHOD on_drag.
sender->get_outtab_line(
EXPORTING i_node_key = node_key
IMPORTING e_outtab_line = dragged ).
drag_drop_object->object = me. " must be bound to trigger drop event when user drops
ENDMETHOD.
METHOD on_drop.
DATA dropped TYPE sflight.
sender->get_outtab_line(
EXPORTING i_node_key = node_key
IMPORTING e_outtab_line = dropped ).
MESSAGE |{ dragged-carrid }-{ dragged-connid }-{ dragged-fldate
} dropped on { dropped-carrid }-{ dropped-connid }-{ dropped-fldate }| TYPE 'I'.
ENDMETHOD.
ENDCLASS.
PARAMETERS dummy.
DATA go_app TYPE REF TO lcl_app.
LOAD-OF-PROGRAM.
CREATE OBJECT go_app.
AT SELECTION-SCREEN OUTPUT.
go_app->at_selection_screen_output( ).
AT SELECTION-SCREEN ON EXIT-COMMAND.
go_app->at_selection_screen_exit( ).
Related
I'm currently designing parallel processing (by using aRFC), for mass GI job.
The problem is - How can i get return of EACH job result?
I used TABLES parameter, which are declared in main report (gt_result), and when aRFC is done, each FM doing MODIFY itab inside the function.
The problem is - inside each job, I checked data is changed(inside the gt_result), but when job is finished, and return to main report program, ITAB wasn't changed!
Is it possible to change ITAB value, using aRFC parallel processing? or Is it other way to get result from each job?
Any help will be appreciated. Thanks!
Edit : Here is a code snippet
Main Report :
DATA: g_task(20) TYPE n VALUE '100', "Task name administration
g_progs TYPE i, "Number of task in progress
g_sprog TYPE i, "Number of task started
g_eprog TYPE i, "Number of task finished
pa_wpnum TYPE int4 VALUE 5,
jobs TYPE int4 VALUE 100. "Number of task to be proceeded
TYPES : BEGIN OF gs_target,
matnr TYPE matnr_d,
cnt TYPE i,
END OF gs_target.
DATA : gt_target TYPE STANDARD TABLE OF gs_target,
wa_target TYPE gs_target.
DATA : gt_6040_para TYPE STANDARD TABLE OF zspp6040_para,
wa_6040_para TYPE zspp6040_para.
DATA : lv_cnt_seqno TYPE i,
lv_flag TYPE c.
DATA : gt_para_test TYPE STANDARD TABLE OF zpara_test,
wa_para_test TYPE zpara_test.
DATA : gv_fs_name(10) TYPE c.
** Test Data Append **
wa_target-matnr = 'A'.
wa_target-cnt = 300.
APPEND wa_target TO gt_target.
wa_target-matnr = 'B'.
wa_target-cnt = 657.
APPEND wa_target TO gt_target.
wa_target-matnr = 'C'.
wa_target-cnt = 1231.
APPEND wa_target TO gt_target.
wa_target-matnr = 'D'.
wa_target-cnt = 831.
APPEND wa_target TO gt_target.
wa_target-matnr = 'E'.
wa_target-cnt = 918.
APPEND wa_target TO gt_target.
** Test Data Append END **
** Split target into 1:300 ratio - for later use?
LOOP AT gt_target INTO wa_target.
DO.
lv_cnt_seqno = 1.
wa_target-cnt = wa_target-cnt - 300.
wa_6040_para-matnr = wa_target-matnr.
wa_6040_para-seqno = lv_cnt_seqno.
APPEND wa_6040_para TO gt_6040_para.
IF wa_target-cnt > 0.
lv_cnt_seqno = lv_cnt_seqno + 1.
ELSEIF wa_target-cnt <= 0.
CLEAR lv_cnt_seqno.
lv_flag = 'X'.
ENDIF.
IF lv_flag = 'X'.
CLEAR : lv_flag.
EXIT.
ENDIF.
ENDDO.
CLEAR : wa_6040_para.
ENDLOOP.
CLEAR : lv_flag.
** End Spliting Part **
** Making 'Data' Part - In real use, it should be the 'item' part of looping BAPI,
** Which are used for making GI document, containing 300 items.
LOOP AT gt_target INTO wa_target.
lv_cnt_seqno = 1.
DO.
wa_para_test-seqno = lv_cnt_seqno.
wa_para_test-matnr = wa_target-matnr.
APPEND wa_para_test TO gt_para_test.
lv_cnt_seqno = lv_cnt_seqno + 1.
IF lv_cnt_seqno = wa_target-cnt.
wa_para_test-seqno = lv_cnt_seqno.
wa_para_test-matnr = wa_target-matnr.
APPEND wa_para_test TO gt_para_test.
lv_flag = 'X'.
ENDIF.
IF lv_flag = 'X'.
CLEAR : lv_flag.
EXIT.
ENDIF.
ENDDO.
ENDLOOP.
** End of 'Data Making' Part.
** aRFC part, sending job for 'Matnr', looping 300 items AND changing gt_6040_para, which are used for checking Success, or Error.
LOOP AT gt_target INTO wa_target.
WAIT UNTIL g_progs LE pa_wpnum.
ADD 1 TO g_progs.
CALL FUNCTION 'Z_PP_PARA_TEST'
STARTING NEW TASK g_task DESTINATION IN GROUP DEFAULT
PERFORMING return_z_pp_para_test ON END OF TASK
EXPORTING
lv_matnr = wa_target-matnr
TABLES
zpara_target = gt_para_test
ztpp6040_change = gt_6040_para.
ADD 1 TO g_task.
ADD 1 TO g_sprog.
ENDLOOP.
** End of aRFC part.
WAIT UNTIL g_sprog <= g_eprog.
LOOP AT gt_6040_para INTO wa_6040_para.
WRITE : wa_6040_para-matnr, wa_6040_para-seqno, wa_6040_para-msgtx, wa_6040_para-msgty.
ENDLOOP.
aRFC Function Part :
FUNCTION z_pp_para_test.
DATA : lv_cnt TYPE int4.
DATA : lv_concat_data(10) TYPE c.
DATA : lv_index TYPE int4.
LOOP AT zpara_target WHERE matnr = lv_matnr.
lv_cnt = lv_cnt + 1.
zpara_target-msgtx = sy-tabix.
MODIFY zpara_target.
IF lv_cnt = 300.
lv_index = lv_index + 1.
READ TABLE ZTPP6040_CHANGE WITH KEY matnr = zpara_target-matnr
seqno = lv_index.
IF sy-subrc = 0.
ZTPP6040_CHANGE-msgty = 'S'.
ZTPP6040_CHANGE-msgtx = lv_index.
MODIFY ZTPP6040_CHANGE index sy-index.
ENDIF.
lv_cnt = 0.
ENDIF.
ENDLOOP.
ENDFUNCTION.
Returning Part
FORM return_z_pp_para_test USING taskname.
RECEIVE RESULTS FROM FUNCTION 'Z_PP_PARA_TEST'.
SUBTRACT 1 FROM g_progs.
ADD 1 TO g_eprog.
ENDFORM.
ZSPP6040_PARA Structure
MATNR MATNR_D
SEQNO INT4
MSGTX BAPI_MTYPE
MSGTY BAPI_MSG
ZPARA_TEST Structure
MATNR MATNR_D
SEQNO INT4
MSGTX BAPI_MTYPE
The RECEIVE RESULTS FROM FUNCTION instruction requires that you state which parameters you would like to receive and where you would like to store the results. Unfortunately all the parameters are optional, and those you don't explicitly mention just get discarded. So calling it with no parameters (like you do here) is pointless but still legal.
You likely declared the table you pass to the aRFC call as a global variable (don't do that!) and then in your FORM return_z_pp_para_test you again access that global table which wasn't changed yet.
In order to receive the actual results of the function-call, do this:
DATA: lt_results_target TYPE STANDARD TABLE OF gs_target,
lt_results_6040 TYPE STANDARD TABLE OF zspp6040_para.
RECEIVE RESULTS FROM FUNCTION 'Z_PP_PARA_TEST'
TABLES
zpara_target = lt_results_target
ztpp6040_change = lt_results_6040.
Now the local tables lt_results_target and lt_results_6040 should contain a copy of the data after it was changed by that asynchronous function-call.
I'm generating an internal table with cl_gui_alv_grid that has five columns and I can't seem to figure out how to sort by column 1 once the table is loaded. I managed to do it with cl_salv_table, however not with the grid. Any idea please? I suppose it's done somehow with the CALL METHOD go_alv->set_sort_criteria however I'm getting a crash when triggering the table view.
DATA: lt_sort TYPE lvc_t_sort,
ls_sort TYPE lvc_s_sort.
FORM sort_data.
REFRESH: lt_sort.
CLEAR: ls_sort.
ls_sort-spos = '1'.
ls_sort-fieldname = 'Column1'.
ls_sort-up = abap_true.
APPEND ls_sort TO lt_sort.
ENDFORM.
FORM first_display.
PERFORM sort_data.
CALL METHOD go_alv->set_table_for_first_display
EXPORTING
i_structure_name = 'TABLE_STRUCTURE'
is_layout = gs_layout
CHANGING
it_outtab = gt_salv_table
ENDFORM.
CALL METHOD go_alv->set_sort_criteria
EXPORTING
it_sort = lt_sort
* EXCEPTIONS
* no_fieldcatalog_available = 1
* others = 2.
Do you call the set_sort_criteria before the set_table_for_first_display? It looks like there is no fieldcatalouge yet, this is why it does not work.
I think more straighforward is: The set_table_for_first_display method has a changing parameter it_sort, just use that one for importing the sort table into the class, no need to call set_sort_criteria:
CALL METHOD go_alv->set_table_for_first_display
EXPORTING
i_structure_name = 'TABLE_STRUCTURE'
is_layout = gs_layout
CHANGING
it_outtab = gt_salv_table
it_sort = lt_sort
EXCEPTIONS
...
I want to pass a range table for OBJNR, e.g.
call method ME->ME_GET_STATUS
exporting
I_OBJNR = <FS_DATA>-OBJNR_NTF
I_AEDAT = LV_AEDAT
I_AEZEIT = LV_AEZEIT
IT_OBJNR = LR_OBJNR
importing ...
In the PUBLIC section of the super class I have:
RT_OBJNR type range of JSTO-OBJNR . (this is inherited by the calling class)
which is used by both calling & called methods.
The method ME_GET_STATUS has a parameter:
IT_OBJNR Importing Type RT_OBJNR Range table for OBJNR
and code
,WA_OBJNR like line of IT_OBJNR
,LR_OBJNR type RT_OBJNR
LR_OBJNR[] = IT_OBJNR[].
The range table is only used to buffer an itab - LT_JCDS.
select S~OBJNR, S~STAT, S~CHGNR, S~UDATE, S~UTIME,
S~INACT, O~OBTYP, O~STSMA
from JCDS as S
join JSTO as O
on O~OBJNR = S~OBJNR
into table #IT_JCDS
where S~OBJNR in #LR_OBJNR
order by S~OBJNR, S~UDATE, S~UTIME, S~STAT, S~CHGNR
loop at IT_JCDS into data(LT_JCDS)
where OBJNR = I_OBJNR
group by ( OBJNR = LT_JCDS-OBJNR STAT = LT_JCDS-STAT
GS = group size GI = group index )
ascending
reference into data(OBJNR_REF)
It all works perfectly if there is just 1 record in the range table.
The issue is that if I pass more than 1 record it still works fine but seems to cause a commit (?) which closes the cursor causing a dump in MCEX_BW_LO_API. This occurs when calling the macro "sel" for the 2nd data package.
The idea is to pass multiple records of 'EQ' and 'BT' selections resulting in fewer records being returned from the database.
I've tried changing to a standard table and using = LR_OBJNR[]
I would like to convert the method below to a nested FOR instead of a nested LOOP, but I don't know how to do it since the inner table is dynamic (it can be one of 5 different types).
TYPES: BEGIN OF ty_result,
lgart TYPE string,
betrg TYPE string,
betpe TYPE string,
END OF ty_result,
ty_results TYPE STANDARD TABLE OF ty_result WITH EMPTY KEY.
DATA: known_table TYPE ty_results,
also_known_table TYPE ty_results,
mt_period_results TYPE ty_results.
FIELD-SYMBOLS: <dynamic_table> TYPE STANDARD TABLE,
<betrg>, <betpe>, <lgart>.
LOOP AT known_table REFERENCE INTO DATA(known_line).
READ TABLE <dynamic_table> TRANSPORTING NO FIELDS WITH KEY ('LGART') = known_line->*-lgart.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(lv_tabix) = sy-tabix.
LOOP AT <dynamic_table> ASSIGNING FIELD-SYMBOL(<dynamic_line>) FROM lv_tabix.
UNASSIGN: <betrg>, <betpe>, <lgart>.
ASSIGN COMPONENT: 'BETPE' OF STRUCTURE <dynamic_line> TO <betpe>,
'BETRG' OF STRUCTURE <dynamic_line> TO <betrg>,
'LGART' OF STRUCTURE <dynamic_line> TO <lgart>.
IF <lgart> <> known_line->*-lgart.
EXIT.
ENDIF.
APPEND VALUE ty_result( lgart = <lgart>
betrg = <betrg>
betpe = <betpe> ) TO mt_period_results.
ENDLOOP.
ENDLOOP.
When the inner table is not dynamic, I can do it like this:
append lines of value zwta_t_results(
for known_line in known_table
for also_known_line in also_known_table
where ( lgart = known_line-lgart )
( lgart = known_line-lgart
betrg = also_known_line-betrg
betpe = also_known_line-betpe ) to mt_period_results.
So the question is: is it possible to use FOR iterator (as the second method) with a dynamic table?
My answer was checked for ABAP 7.52. Unfortunately, it's currently only possible to use a subset of the static variant of ASSIGN by using LET <fs> = writable_expression IN inside a construction expression (including "FOR" table iterations), where the "writable expression" is limited to a table expression, NEW and CAST. So it's rather limited, there are no equivalences for the dynamic variants of ASSIGN, so you can use only workarounds.
The syntax after WHERE allows a dynamic expression, so it will be possible to enter WHERE ('LGART = KNOWN_LINE-LGART'). However, it could be very counter-performing if the loop is nested inside another loop (as it is in your case), so an index should be defined so that to accelerate the iteration. If a secondary index is to be used, then the condition should be USING KEY ('KEYNAME') WHERE ('LGART = KNOWN_LINE-LGART').
Now, here is a workaround for your particular case: you define statically the names of the components, so one possibility is to define a static structure with those component names and use the CORRESPONDING construction operator. Note that I didn't test it, but I think for several reasons that the performance of using CORRESPONDING is faster in your case than using ASSIGN.
The following code should work. I assume that the internal table behind <dynamic_table> has a primary key sorted by LGART (TYPE SORTED TABLE OF ... WITH NON-UNIQUE KEY lgart) so that the performance is good:
TYPES: BEGIN OF ty_struc,
lgart TYPE string,
betrg TYPE string,
betpe TYPE string,
END OF ty_struc.
known_table = VALUE #( ( lgart = 'A' ) ( lgart = 'B' ) ).
also_known_table = VALUE #( ( lgart = 'A' ) ( lgart = 'C' ) ( lgart = 'A' ) ).
ASSIGN also_known_table TO <dynamic_table>.
APPEND LINES OF
VALUE ty_results(
FOR known_line IN known_table
FOR <inner_line> IN <dynamic_table>
WHERE ('LGART = KNOWN_LINE-LGART')
LET struc = CORRESPONDING ty_struc( <inner_line> ) IN
( lgart = known_line-lgart
betrg = struc-betrg
betpe = struc-betpe ) )
TO mt_period_results.
I am getting the correct Employee Id in the VarEmpID variable. When I click on delete
It is giving me
Unable to cast object of type 'System.Data.Linq.DataQuery`1[my name space]' to type 'namespace'.
enter code here
Protected Sub radGrid1_DeleteCommand(ByVal source As Object, ByVal e As GridCommandEventArgs) Handles radGrid1.DeleteCommand
Dim VarEmpId As String = (CType(e.Item, GridDataItem)).OwnerTableView.DataKeyValues(e.Item.ItemIndex)("EmpId").ToString()
Using dc1 As New EmployeesDataClassesDataContext()
Dim EmployeeEntry = (From p In dc1.Employees
Where (p.EmpId = VarEmpId)
Select p)
dc1.Employees.DeleteOnSubmit(EmployeeEntry)
dc1.SubmitChanges()
Dim queryResults = (From queryItem In EmployeeEntry Select queryItem).ToList()
If queryResults.Any Then
radGrid1.DataSource = queryResults
radGrid1.DataBind()
End If
End Using
End Sub
dc1.Employees.DeleteOnSubmit(EmployeeEntry)
That method expects an Employee instance. Instead, you passed in an employee query.
Dim EmployeeEntry = ( query )
This is a query, not an entry. Consider calling Enumerable.First to get the first result of the query, and then deleting that.
Modified added Dim EmployeeEntry = (From p In dc1.Employees Where (p.EmpId = VarEmpId) Select p).singleorDefault() After that commented out the queryresults part and binded data again it solved my problem. – SmilingLily