ABAP - cl_gui_toolbar->delete_all_buttons not working - abap

DATA: lo_toolbar TYPE REF TO cl_gui_toolbar.
lo_Tree->get_toolbar_object(
IMPORTING
er_toolbar = lo_toolbar " Toolbar Object
).
lo_toolbar->delete_all_buttons(
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.
"add my own buttons
lo_toolbar->add_button(
EXPORTING
fcode = 'ADDROOT' " Function Code Associated with Button
icon = '#04#' " Icon Name Defined Like "#0a#"
butn_type = cntb_btype_button " Button Types Defined in CNTB
quickinfo = 'Create new portfolio' " Purpose of Button Text
EXCEPTIONS
cntl_error = 1
cntb_btype_error = 2
cntb_error_fcode = 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.
I have instance of class cl_gui_alv_tree. And i want to delete standard buttons in toolbar and add my own. So I call get_toolbar_object and its method delete_all_buttons but it doesn't work. The output is my button at first position and then standard buttons. Could you help me with that?

If You inspect the code inside the method called "delete_all_buttons", then you will see a call to another method called, "call_method". This is simply an invocation, AKA dynamic method call of methods, which can be passed as arguments,
then You will see many lines like these: (do not bother, if it sounds weird, that is, how dynamic method calls are built. At least one way, but in this case we are dealing with ABAP and OLE beyond this scope by the way) .
WHEN 3.
CALL METHOD OF H_CONTROL-OBJ VERB = RESULT NO FLUSH
EXPORTING #1 = P1
#2 = P2
#3 = P3.
Or some like these:
WHEN 14.
CALL METHOD OF H_CONTROL-OBJ VERB = RESULT NO FLUSH QUEUEONLY
EXPORTING #1 = P1
#2 = P2
#3 = P3
#4 = P4
#5 = P5
#6 = P6
#7 = P7
#8 = P8
#9 = P9
#10 = P10
#11 = P11
#12 = P12
#13 = P13
#14 = P14.
What You should notice are the keywords "NO FLUSH" and/or "QUEUE ONLY".
For further information mark them and hit F1. The OLE-documentation tells You more if, desired .
They imply, that the sap-gui-frontend will NOT be notified, regardless, what changes are made to the backend's object-representators, only the backend knows the new state, changings, removals, etc.
In general any pbo/pai should synchronize frontend and backend, in fact I even think, only those, where QUEUEONLY is set, are automatically synced on the next cycle.
If You want to force synchronization, just call the static method of the gui-class-control-framwork-base, AKA cl_gui_cfw.
The proper method call will be ( in fact it is the best choice if You want to alter ui controls BUT You cannot rely on any pbo/pai-cycle ) :
CALL METHOD cl_gui_cfw=>flush.
Could I help You ?

Related

Changes don't commit after RFC of ME_INFORECORD_MAINTAIN_MULTI

I'm calling ME_INFORECORD_MAINTAIN_MULTI with an RFC. The purchase info records get a new number, but the changes aren't commited to the db.
The commit is supposed to be implicit after a RFC, but it isn't. I've tried adding an explicit COMMIT WORK after the function call, but this didn't help.
The changes are commited properly if I use a regular function call (not remote), however performance is very slow.
Please help.
FORM CALL_BAPI_PIR.
lv_taskname = |PIR-{ lv_sentjobs WIDTH = 3 ALIGN = RIGHT PAD = '0' }|.
CALL FUNCTION 'ME_INFORECORD_MAINTAIN_MULTI'
STARTING NEW TASK lv_taskname
DESTINATION IN GROUP DEFAULT
PERFORMING RETURN_BAPI_PIR ON END OF TASK
EXPORTING
testrun = p_test
TABLES
t_eina = GT_ME_EINA
t_einax = GT_ME_EINAX
t_eine = GT_ME_EINE
t_einex = GT_ME_EINEX
return = GT_ME_INFORECORD_RETURN
EXCEPTIONS
system_failure = 1 MESSAGE lv_exceptionmsg
communication_failure = 2 MESSAGE lv_exceptionmsg
resource_failure = 3
.
CASE sy-subrc.
WHEN 0.
lv_sentjobs = lv_sentjobs + 1.
COMMIT WORK.
WHEN 1 OR 2.
MESSAGE lv_exceptionmsg TYPE 'I'.
WRITE: / lv_taskname, ':', lv_exceptionmsg.
ENDCASE.
ENDFORM.
FORM RETURN_BAPI_PIR USING TASKNAME.
DATA INFO LIKE RFCSI.
RECEIVE RESULTS FROM FUNCTION 'ME_INFORECORD_MAINTAIN_MULTI'
IMPORTING
RFCSI_EXPORT = INFO
RETURN = GT_ME_INFORECORD_RETURN.
lv_recvjobs = lv_recvjobs + 1.
ENDFORM.
I've solved this by making a wrapper function that ends with a commit, and calling the wrapper function instead of the standard function.
FUNCTION z_inforecord_maintain_mult2
IMPORTING
VALUE(testrun) TYPE bapiflag-bapiflag OPTIONAL
EXPORTING
VALUE(et_eina) TYPE mewieina_mig_t
VALUE(et_eine) TYPE mewieine_t
TABLES
t_eina TYPE mewieina_mig_t OPTIONAL
t_einax TYPE mewieinax_t OPTIONAL
t_eine TYPE mewieine_t OPTIONAL
t_einex TYPE mewieinex_t OPTIONAL
txt_lines TYPE mewipirtext_tt OPTIONAL
cond_validity TYPE mewivalidity_tt OPTIONAL
condition TYPE mewicondition_tt OPTIONAL
cond_scale_value TYPE mewiscaleval_tt OPTIONAL
cond_scale_quan TYPE mewiscalequan_tt OPTIONAL
return TYPE fs4mig_t_bapiret2 OPTIONAL.
CALL FUNCTION 'ME_INFORECORD_MAINTAIN_MULTI'
EXPORTING
testrun = testrun
IMPORTING
et_eina = et_eina
et_eine = et_eine
TABLES
t_eina = t_eina
t_einax = t_einax
t_eine = t_eine
t_einex = t_einex
txt_lines = txt_lines
cond_validity = cond_validity
condition = condition
cond_scale_value = cond_scale_value
cond_scale_quan = cond_scale_quan
return = return
.
IF SY-subrc = 0.
COMMIT WORK.
ENDIF.
ENDFUNCTION.
With RFC, there's an implicit database commit at some point of time in the calling program, but not in the RFC session, like there's no implicit database commit after SUBMIT.
You may chain several function module calls in the same RFC session, and to chain a SAP LUW commit in the RFC session you may call the function module BAPI_TRANSACTION_COMMIT to do a COMMIT WORK. The solution then depends on the type of RFC you use.
In your case, you use asynchronous RFC with a callback i.e. with wait, so the solution will be to
indicate KEEPING TASK at RECEIVE RESULTS so that to keep the RFC session open after calling ME_INFORECORD_MAINTAIN_MULTI
use WAIT FOR ASYNCHRONOUS TASKS so that BAPI_TRANSACTION_COMMIT is called sequentially after ME_INFORECORD_MAINTAIN_MULTI has ended.
CALL FUNCTION 'ME_INFORECORD_MAINTAIN_MULTI'
STARTING NEW TASK lv_taskname
DESTINATION IN GROUP DEFAULT
PERFORMING RETURN_BAPI_PIR ON END OF TASK
...
EXCEPTIONS
system_failure = 1 MESSAGE lv_exceptionmsg
communication_failure = 2 MESSAGE lv_exceptionmsg
resource_failure = 3.
IF sy-subrc = 0.
WAIT FOR ASYNCHRONOUS TASKS UNTIL lv_recvjobs = lv_sentjobs.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
STARTING NEW TASK lv_taskname " <====== reuse existing RFC session/closed implicitly right after
DESTINATION IN GROUP DEFAULT
EXCEPTIONS
system_failure = 1 MESSAGE lv_exceptionmsg
communication_failure = 2 MESSAGE lv_exceptionmsg
resource_failure = 3.
...
FORM RETURN_BAPI_PIR USING TASKNAME.
DATA INFO LIKE RFCSI.
RECEIVE RESULTS FROM FUNCTION 'ME_INFORECORD_MAINTAIN_MULTI'
KEEPING TASK " <============== add this to not close the RFC session
IMPORTING
RFCSI_EXPORT = INFO
RETURN = GT_ME_INFORECORD_RETURN.
lv_recvjobs = lv_recvjobs + 1.
ENDFORM.
NB:
I did not handle the exceptions to simplify the demonstration.
If you run the RFC under several task names, several RFC sessions are started, so you must call BAPI_TRANSACTION_COMMIT in each of these RFC sesssions.

Create outbound delivery with different shipping address

I've searched for days and found nothing. My problem is, that I have to create a return delivery out of an QM-Report. Everything works fine.
However, the customer wants to change the delivery address manually.
Flow:
QM02 (QM-Report) => Return order with BAPI_PO_CREATE1 (different address works fine) => Delivery with BAPI_OUTB_DELIVERY_CREATE_STO (different address from PO not working)
My question:
Is there a possibility to change the delivery address of the outbound delivery? Do I have to implement a BADI or is there a simple solution?
If anything is missing, I will update the question.
Function BAPI_OUTB_DELIVERY_CREATE_STO allows you to create deliveries from PO but you can't handle many of the delivery fields.
After you have created the deliveries, you should use WS_DELIVERY_UPDATE_2 function to update any field.
This is not a BAPI, and consequently it is not well documented, but is widely used for these changes.
Best regards
UPDATE
Here's a snippet:
ls_vbkok-vbeln_vl = <delivery number>.
ls_partners-vbeln_vl = ls_vbkok-vbeln_vl.
ls_partners-parvw = 'WE'.
ls_partners-parnr = <partner number>.
ls_partners-updkz_par = 'U'.
ls_partners-stras = <new street address>.
append ls_partners to lt_partners.
call function 'WS_DELIVERY_UPDATE_2'
exporting
vbkok_wa = ls_vbkok
synchron = 'X'
commit = 'X'
delivery = ls_vbkok-vbeln_vl
tables
vbpok_tab = lt_vbpok
it_partner_update = lt_partners
prot = lt_prot.
if lt_prot[] is not initial.
" handle error message here
endif.
if you need to make a commit and you can do it after the 'WS_DELIVERY_UPDATE_2' , try to call it in a new task.
for exemple :
call function 'WS_DELIVERY_UPDATE_2' STARTING NEW TASK task
PERFORMING return_fm ON END OF TASK
exporting
vbkok_wa = ls_vbkok
synchron = 'X'
commit = ' '
delivery = ls_vbkok-vbeln_vl
tables
vbpok_tab = lt_vbpok
it_partner_update = lt_partners
prot = lt_prot.
*your code
WAIT UNTIL get_executed <> space.
FORM return_fm USING i_taskname.
*your code
get_executed = 'X'.
ENDFORM.

How to extract the value of the field on user-command(click) for interactive ALV?

The below code is the form which will pop up the new window after clicking on the hotspot enabled field. I want to print the value of the field (hotspot enabled) that is clicked.
FORM user_command USING r_ucomm TYPE sy-ucomm
rs_selfield TYPE slis_selfield.
ENDFORM.
I guess you talk about the ALV Grid. So you use a FM called REUSE_ALV_GRID_DISPLAY. There is a exporting parameter called I_callback_user_command. In this parameter you have to set the form name of your program. For Example:
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_bypassing_buffer = 'X'
it_fieldcat = lt_fieldcat
i_callback_program = sy-repid
i_save = 'A'
i_callback_user_command = 'USER_COMMAND'
is_variant = ls_variant
TABLES
t_outtab = lt_qmel_mat
EXCEPTIONS
program_error = 1
OTHERS = 9.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
And the Form:
FORM user_command USING rf_ucomm LIKE sy-ucomm
selfield TYPE slis_selfield.
DATA: lv_qmnum TYPE qmnum.
CASE selfield-fieldname.
WHEN 'QMNUM'.
"Code
ENDCASE.
ENDFORM.
I hope that helps you.

ABAP Webdynpro error in supply function for a singleton

The following error text was processed in system EH5 : Invalid operand type for the MOVE-CORRESPONDING statement.
◾ The error occurred on the application server CRMEHP2_EH5_24 and in the work process 8 .
◾ The termination type was: RABAX_STATE
◾ The ABAP call stack was:
Method: IF_WD_CONTEXT_ELEMENT~GET_STATIC_ATTRIBUTES of program CL_WDR_CONTEXT_ELEMENT========CP
Method: BOOKINGS_READ of program /1BCWDY/0AA4D2ZOSMXD1LD8M8M2==CP
Method: BOOKINGS_READ of program /1BCWDY/0AA4D2ZOSMXD1LD8M8M2==CP
Method: SUPPLY_ELEMENTS of program CL_WDR_CONTEXT_NODE_VAL=======CP
Method: IF_WD_CONTEXT_NODE~GET_LEAD_SELECTION of program CL_WDR_CONTEXT_NODE_VAL=======CP
Method: IF_WD_CONTEXT_NODE~GET_LEAD_SELECTION of program CL_WDR_CONTEXT_NODE_MAP=======CP
Method: GET_LEAD_SELECTION of program CL_WDR_TABLE_DATA_PROVIDER====CP
Method: UPDATE_RANGE_SELECT_START of program CL_WDR_TABLE_DATA_PROVIDER====CP
Method: GET_TABLE_DATA of program CL_WDR_TABLE_DATA_PROVIDER====CP
Method: GET_VISIBLE_TABLE_DATA of program CL_WDR_TABLE_DATA_PROVIDER====CP
I have created two controllers
Componentcontroller is bound to flightinfo table. This table is populated. However, if_componentcontroller=>element_flightinfo dosen't fetch any data. Why?
Customcontroller2 is bound to bookingtab table.
Method:
**METHOD bookings_read.**
DATA:
stru_flight TYPE if_componentcontroller=>element_flightinfo,
itab_booking TYPE if_customcontroller2=>elements_bookingtab.
* Get Parent Element.
* Error is here: All attributes of stru_flight are either blank or zero.
* The error disappears once CALL METHOD is commented.
CALL METHOD parent_element->get_static_attributes
IMPORTING
static_attributes = stru_flight.
* read bookings
*Rest of the satatements work fine.
SELECT * FROM sbook
INTO CORRESPONDING FIELDS OF TABLE itab_booking
WHERE carrid = stru_flight-carrid
AND connid = stru_flight-connid
AND fldate = stru_flight-fldate.
* bind all the elements
node->bind_table(
new_items = itab_booking
set_initial_elements = abap_true ).
**ENDMETHOD.**
Definition of parent_element, and stru_flights structure
NODE Importing IF_WD_CONTEXT_NODE
PARENT_ELEMENT Importing IF_WD_CONTEXT_ELEMENT
stru_flight TYPE if_componentcontroller=>element_flightinfo,
**CALL METHOD parent_element->get_static_attributes
IMPORTING
static_attributes = stru_flight.**
implicit constant definition for context node bookingtab types:
Element_bookingtab type SBOOK,
Elements_bookingtab type standard table of Element_bookingtab with default key.

COMMUNICATION_FAILURE during a Webdynpro BAPI call?

I have created a simple WebDynpro application that calls a BAPI. However, i am getting an error as RFC is not setup.
How do i setup the RFC call?
Error:
The URL call http://crmehp.sat.com:8024/sap/bc/webdynpro/sap/zwd_bapi_call was terminated because of an error.
The following error text was processed in system EH5 : RFC Exception COMMUNICATION_FAILURE with Message RFC destination BAPI Call does not exist. Occurred
◾ The error occurred on the application server CRMEHP2_EH5_24 and in the work process 0 .
◾ The termination type was: RABAX_STATE
◾ The ABAP call stack was:
Method: EXECUTE_BAPI_FLIGHT_GETLIST of program /1BCWDY/0AA4D2ZOSMWRNSH8KCQZ==CP
Method: IF_COMPONENTCONTROLLER~EXECUTE_BAPI_FLIGHT_GETLIST of program /1BCWDY/0AA4D2ZOSMWRNSH8KCQZ==CP
Method: WDDOINIT of program /1BCWDY/0AA4D2ZOSMWRNSH8KCQZ==CP
Method: IF_WDR_VIEW_DELEGATE~WD_DO_INIT of program /1BCWDY/0AA4D2ZOSMWRNSH8KCQZ==CP
Method: DO_INIT of program CL_WDR_DELEGATING_VIEW========CP
Method: INIT_CONTROLLER of program CL_WDR_CONTROLLER=============CP
Method: INIT_CONTROLLER of program CL_WDR_VIEW===================CP
Method: INIT of program CL_WDR_CONTROLLER=============CP
Method: GET_VIEW of program CL_WDR_VIEW_MANAGER===========CP
Method: BIND_ROOT of program CL_WDR_VIEW_MANAGER===========CP
Calling procedure bapi_flight_getlist in WDDOINIT method of webdynpro:
method WDDOINIT .
DATA lo_componentcontroller TYPE REF TO ig_componentcontroller .
lo_componentcontroller = wd_this->get_componentcontroller_ctr( ).
lo_componentcontroller->execute_bapi_flight_getlist(
airline = 'AA' " bapisflkey-airlineid
* destination_from = " bapisfldst
* destination_to = " bapisfldst
* max_rows = " bapisflaux-bapimaxrow
).
endmethod.
execute_bapi_flight_getlist defination:
CALL FUNCTION 'BAPI_FLIGHT_GETLIST'
DESTINATION 'BAPI Call'
EXPORTING
airline = airline
destination_from = destination_from
destination_to = destination_to
max_rows = max_rows
TABLES
date_range = lt_c_date_range
extension_in = lt_c_extension_in
flight_list = lt_c_flight_list
extension_out = lt_c_extension_out
return = lt_c_return
EXCEPTIONS
system_failure = 1 MESSAGE lv_rfc_error
communication_failure = 2 MESSAGE lv_rfc_error.
I checked sm59 and a BAPI Call RFC dosen't exist. However, there are other RFC connections that work.
Assuming you don't want to call a remote system:
Change
DESTINATION 'BAPI Call'
To
DESTINATION 'NONE'
If it is a remote system, create a destination in SM59 (but without the space) and reference that instead.