ABAP Webdynpro error in supply function for a singleton - abap

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.

Related

How to create a txt-file on the application server filled with an internal table?

I'm learning ABAP at the moment and got the task to build a function that creates a .txt file or a .csv file from an internal table and save it on the application server.
I know you can use, for example, GUI_DOWNLOAD for that, but the task is to build my own function to do that.
So I got an internal table filled and I want that to be saved as .txt file on the AS. I'm coding in Eclipse, BTW.
Anybody has an idea how to do that, using a function?
EDIT:
Here's what I tried already:
I created a function in the function builder. On the import parameters I put a parameter with the name "lv_mytab" with type table.
The source code of my function looks like this:
*"-------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*" IMPORTING
*" REFERENCE(LV_MYTAB) TYPE TABLE
*"-------------------------------------------------------------------
DATA(myfile) = '/usr/sap/S42/data/textfile.txt'.
OPEN DATASET myfile FOR OUTPUT IN TEXT MODE ENCODING DEFAULT WITH SMART LINEFEED.
LOOP AT lv_mytab into lt_table.
TRANSFER lt_table to myfile.
CLOSE DATASET myfile.
In my program I tried calling the function like this:
CALL FUNCTION 'EXPORT_TXT_CSV_MR'
EXPORTING
lv_mytab = lt_summe.
lt_summe is the internal table I want to be exported as txt or csv.
Something like this:
OPEN DATASET lv_p_app FOR OUTPUT IN TEXT MODE ENCODING DEFAULT.
LOOP AT gt_error INTO gs_final.
TRANSFER gs_final TO lv_p_app.
ENDLOOP.
CLOSE DATASET lv_p_app.
ENDIF.
More samples here https://answers.sap.com/questions/3704234/download-internal-table-onto-the-application-serve.html
Okay with the help of a fellow student I got it working.
Heres the solution I found:
Code source of the function:
FUNCTION EXPORT_TXT_CSV_MR.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*" IMPORTING
*" REFERENCE(S_FILENAME) TYPE STRING
*" CHANGING
*" REFERENCE(GT_MYTAB) TYPE STANDARD TABLE
*" REFERENCE(GD_VERARBEITUNG) TYPE INT4
*"----------------------------------------------------------------------
DATA:
ld_filename TYPE string,
ld_datei type standard table of sbook,
ld_Zeile like line of ld_datei,
gd_useraction TYPE i,
lt_Ausgabe TYPE STANDARD TABLE OF sbook.
CONCATENATE '/usr/sap/S42/data/' s_filename into ld_filename.
IF gd_Verarbeitung = 1.
ld_datei = gt_mytab.
OPEN DATASET ld_filename FOR OUTPUT IN TEXT MODE ENCODING DEFAULT.
LOOP AT ld_datei into ld_Zeile.
Data(ld_string) = | Partnernummer: { ld_Zeile-customid } Betrag: { ld_Zeile-forcuram } Waehrung: { ld_Zeile-forcurkey } Name: { ld_Zeile-passname }|.
Transfer ld_string to ld_filename.
ENDLOOP.
Close dataset ld_filename.
ElseIF gd_Verarbeitung = 2.
ld_datei = gt_mytab.
*ld_filename = '/usr/sap/S42/data/CSVFile_MR.csv'.
Open Dataset ld_filename for output in text mode encoding default with SMART LINEFEED.
LOOP AT ld_datei into ld_Zeile.
ld_string = | Partnernummer: { ld_Zeile-customid } Betrag: { ld_Zeile-forcuram } Waehrung: { ld_Zeile-forcurkey } Name: { ld_Zeile-passname }|.
Transfer ld_string to ld_filename.
ENDLOOP.
Close dataset ld_filename.
ENDIF.
ENDFUNCTION.
And in my program I call it like this:
if p_txt = 'X'.
ld_txtcsv = 1.
CALL FUNCTION 'EXPORT_TXT_CSV_MR'
EXPORTING
s_filename = 'TXTFile_MR.txt'
CHANGING
gt_mytab = lt_summe
gd_verarbeitung = ld_txtcsv.
clear ld_txtcsv.
endif.
if p_csv = 'X'.
ld_txtcsv = 2.
CALL FUNCTION 'EXPORT_TXT_CSV_MR'
EXPORTING
s_filename = 'CSVFile_MR.csv'
CHANGING
gt_mytab = lt_summe
gd_verarbeitung = ld_txtcsv.
clear ld_txtcsv.
ENDIF.
Thanks for all of your help! I got it now! :)

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.

Open Document returns error (SOFFICEINTEGRATION)

I'm trying to open a Excel file with SOFFICEINTEGRATION to modify the file inplace.
But I always get the CALL_NOT_FLUSHED error, I tried several code snippets (with no_flush = X and no_flush = ' ')
The error "CALL_NOT_FLUSHED" is appearing after calling proxy->open_document
My current code:
DATA proxy TYPE REF TO i_oi_document_proxy.
PARAMETERS dummy.
AT SELECTION-SCREEN OUTPUT.
IF proxy IS NOT BOUND.
CALL METHOD c_oi_container_control_creator=>get_container_control
IMPORTING
control = DATA(lo_container_control)
retcode = DATA(l_rc).
CALL METHOD lo_container_control->init_control
EXPORTING
r3_application_name = 'EXCEL' "#EC NOTEXT
inplace_enabled = 'X'
inplace_scroll_documents = 'X'
parent = cl_gui_container=>screen0
IMPORTING
retcode = l_rc.
CALL METHOD lo_container_control->get_document_proxy
EXPORTING
document_type = 'EXCEL.SHEET'
IMPORTING
document_proxy = proxy.
CALL METHOD proxy->open_document
EXPORTING
document_url = 'file://C:\Users\yourusername\Documents\test.xlsx'
open_inplace = 'X'
IMPORTING
error = DATA(openerr).
ENDIF.

How to use ENQUEUEGETSTAT function module in Gateway service

How can I use ENQUEUEGETSTAT function module in gateway service, this fm returns 3 parameter (ENTRIES_TOTAL, ENTRIES_PEAK, ENTRIES_ACTUAL)
I can map tables in Gateway but cant figure out this. How can I collect these parameters in to internal table and export then?
it looks like a function import use case to me .
First of all, you have to define a ABAP structure for the returning data like below
#EndUserText.label : 'ENQUEUEGETSTAT'
#AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE
define structure zza_enqueuegetstat {
entries_total : abap.int4;
entries_peak : abap.int4;
entries_actual : abap.int4;
}
In your SEGW project, create a entity type ENQUEUEGETSTAT mapping to this structure.
.
Afterwards, create a function import ENQUEUEGETSTAT.
Go to your DPC_EXT class and redefine the method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~EXECUTE_ACTION.
method /iwbep/if_mgw_appl_srv_runtime~execute_action.
data ls_enqueuegetstat type zza_enqueuegetstat.
if iv_action_name = 'ENQUEUEGETSTAT'.
call function 'ENQUEUEGETSTAT'
importing
entries_total = ls_enqueuegetstat-entries_actual
entries_peak = ls_enqueuegetstat-entries_peak
entries_actual = ls_enqueuegetstat-entries_total.
copy_data_to_ref(
exporting
is_data = ls_enqueuegetstat
changing
cr_data = er_data
).
endif.
endmethod.
Save and activate everything. Then you should able to access your function import /sap/opu/odata/sap/**YOUR_SERVICE**/ENQUEUEGETSTAT?$format=json
{
"d": {
"EntriesTotal": 382,
"EntriesPeak": 43189,
"EntriesActual": 500000
}
}
Hope it helps.

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.