Why is r_data_line_descr of cl_salv_bs_runtime_info=>get_data_ref() not bound? - sap

I have this code, which has been working very nice for several months now:
SUBMIT (IV_REPORT_NAME)
WITH SELECTION-TABLE selection_table
USING SELECTION-SET IV_SELECTION_SET_VARIANT
AND RETURN.
FIELD-SYMBOLS <lt_data> TYPE ANY TABLE.
FIELD-SYMBOLS <lt_data_line> TYPE ANY TABLE.
DATA lr_data TYPE REF TO data.
DATA lr_data_line TYPE REF TO data.
DATA lr_data_descr TYPE REF TO cl_abap_datadescr.
DATA lr_data_line_descr TYPE REF TO cl_abap_datadescr.
cl_salv_bs_runtime_info=>get_data_ref(
IMPORTING r_data_descr = lr_data_descr
r_data_line_descr = lr_data_line_descr ).
IF lr_data_descr IS NOT BOUND.
ev_result_json = '[]'.
EXIT.
ENDIF.
....
But for one reports lr_data_descr is "NOT BOUND" if called via rfc.
It works if I run the function module via "test" in se80. But if I call it via rfc it is not bound. I use the very same user (type "service") for RFC and SE80.
With other words: Same input and same code. It works with normal debugging, but fails (not bound) with remote debugging.
Why is there a difference?
Is there a way to get some error message?
This would really help, if I could get the reason why it is not bound.
I debugged into get_data_ref():
This line behaves different:
import t_component to lt_component from memory id cl_salv_bs_runtime_info=>c_memid_data_def.
if sy-subrc eq 0.
If I test the function module in se80 sy-subrc is 0. If I do external debugging (same user), then sys-subrc is 4.
It is an adhoc report. It's name: AQZZZMM=========ZME80FN=======

Related

How to import parameter of type ANY?

How can I put what a method, in this example get_properties, is giving me into a local variable when the type of the parameter is ANY?
"ES_ATTRIBUTES Exporting Type ANY
some_object->get_properties( IMPORTING es_attributes = ????? ).
I tried to put it into this variable, but that didn't work:
FIELD-SYMBOLS:
<ls_attributes> TYPE any.
In ABAP, it means that you may use a data object of any type (the simplest way is to declare it with DATA).
But it may be more restrictive according to the way the developer has coded his method.
Here, I recognize a method of WebUI Components (CRM, SOLMAN, …) so the data object must correspond to the "some_object" you are accessing. Do a debug of GET_PROPERTIES if you are not sure.
Actually as a caller, you should know the type you want to import for this ANY parameter.
You have to know the protocol of GET_PROPERTIES and debug it to know the return type of the parameter. In your method, you create a DATA REFERENCE and have it assigned to a ANY field symbol.
Data:
lr_data type ref to data.
Field-symbols:
<lt_properties> type any.
create data lr_data type TYPE_NAME. 'You should know the type
assign lr_data->* to <lt_properties>.
From my personal view, it is not a very good practice to define a method with EXPORTING parameter type ANY.
You either define a interface with IF_**_PROPERTY and you have a return TABLE of this interface.
or you return a name-value pair table. (From the method signature, it should return a TABLE, GET_PROPERTIES).
I tried to put it into this variable, but that didn't work:
What error do you get?
Here is the sample with the standard structure-converting class which also has ANY-typed parameter ex_value, and it works with ANY field-symbols wonderfully.
DATA: gattrdata LIKE brelattr-gattrdata.
FIELD-SYMBOLS: <fs_incl> TYPE ANY, <fs_wa> TYPE str_type.
CALL METHOD cl_abap_container_utilities=>read_container_c
EXPORTING
im_container = gattrdata
IMPORTING
ex_value = <fs_incl>
EXCEPTIONS
illegal_parameter_type = 1
OTHERS = 2.
CHECK sy-subrc = 0.
MOVE-CORRESPONDING <fs_incl> TO <fs_wa>.
In such cases you can guess the type with RTTS and then replace field-symbol with typed reference ref_wa:
DATA: ref_wa TYPE REF TO data,
ref_rowtype TYPE REF TO cl_abap_structdescr.
ref_rowtype ?= cl_abap_typedescr=>describe_by_data( <fs_incl> ).
CREATE DATA ref_wa TYPE HANDLE ref_rowtype.
but it is definitely better/safe to know the type in advance as Sandra said.

Modifying EKPO Fields in ME21n - ME_PROCESS_PO_CUST BADI

I am trying to modify the values of field WEORA and BSTAE in ME21n upon saving. I've written my codes in ME_PROCESS_PO_CUST BADI, in method CHECK. Below is my code.
DATA: lt_data TYPE PURCHASE_ORDER_ITEMS,
lo_header TYPE REF TO CL_PO_HEADER_HANDLE_MM,
lt_item TYPE REF TO IF_PURCHASE_ORDER_ITEM_MM,
ls_get_item TYPE MEPOITEM,
ls_set_item TYPE MEPOITEM,
lv_firewall TYPE abap_bool.
FIELD-SYMBOLS: <fs_data> TYPE PURCHASE_ORDER_ITEM.
lt_data = im_header->get_items( ).
READ TABLE lt_data ASSIGNING <fs_data> INDEX 1.
IF <fs_data> IS ASSIGNED.
lt_item = <fs_data>-item.
ENDIF.
ls_get_item = lt_item->get_data( ).
ls_get_item-bstae = '0004'.
ls_get_item-weora = abap_true.
CALL METHOD lt_item->set_data
EXPORTING
im_data = ls_get_item.
I tried debugging it, but inside the method set_data there is a condition:
CHECK l_parent->my_ibs_firewall_on EQ mmpur_yes OR
l_parent->my_cust_firewall_on EQ mmpur_yes.
The value of bot is initial so it doesn't go through the whole set_data code. But I also tried forcing one of them to abap_true (for it to go through the rest of the code) but updating the fields also doesn't work.
It seems like this BADI isn't working but I made my research and most of them uses this BADI to update EKPO fields in ME21n. Is there any problem with my code? And is there other exit I can use to update fields WEORA and BSTAE in transaction code ME21N upon saving?
You have to call method SET_DATAX and then SET_DATA.
SET_DATAX , you will mark X to field you want to update values.
Regards,
Umar Abdullah

Something similar to LIST_TO_ASCI with support of JSON/XML

I know that I can use LIST_TO_ASCI to convert a report to ASCII.
But I would like to have a more high level data format like json,XML,CSV.
Is there a way to get something that is easier to handle then ASCII?
Here is what the report looks like in SAP:
The conversion needs to be executed in ABAP on a result which was executed like this:
SUBMIT <REPORT_NAME> ... EXPORTING LIST TO MEMORY AND RETURN.
You can get access to SUBMIT list in memory like this:
call function 'LIST_FROM_MEMORY'
TABLES
listobject = t_list
EXCEPTIONS
not_found = 1
others = 2.
if sy-subrc <> 0.
message 'Unable to get list from memory' type 'E'.
endif.
call function 'WRITE_LIST'
TABLES
listobject = t_list
EXCEPTIONS
EMPTY_LIST = 1
OTHERS = 2
.
if sy-subrc <> 0.
message 'Unable to write list' type 'E'.
endif.
And the final step of the solution (conversion of result table to JSON) was already answered to you in your question.
I found a solution here: http://zevolving.com/2015/07/salv-table-22-get-data-directly-after-submit/
This is the code:
DATA: lt_outtab TYPE STANDARD TABLE OF alv_t_t2.
FIELD-SYMBOLS: <lt_outtab> like lt_outtab.
DATA lo_data TYPE REF TO data.
" Let know the model
cl_salv_bs_runtime_info=>set(
EXPORTING
display = abap_false
metadata = abap_false
data = abap_true
).
SUBMIT salv_demo_table_simple
AND RETURN.
TRY.
" get data from SALV model
cl_salv_bs_runtime_info=>get_data_ref(
IMPORTING
r_data = lo_data
).
ASSIGN lo_data->* to <lt_outtab>.
BREAK-POINT.
CATCH cx_salv_bs_sc_runtime_info.
ENDTRY.
Big thanks to Sandra Rossi, she gave me the hint to cx_salv_bs_sc_runtime_info.
Related answer: https://stackoverflow.com/a/52834118/633961

Short dump when using built-in SLIS-function in ALV

I'm still pretty new to ABAP and while (trying) making an ALV I get an crash report when executing the program. To create an ALV I have followed a few tutorials and stuff and at the moment it looks like this:
TYPE-POOLS: slis.
*build field catalog
DATA: it_fieldcat TYPE slis_t_fieldcat_alv,
wa_fieldcat TYPE slis_fieldcat_alv,
repid TYPE sy-repid.
REFRESH it_fieldcat.
CLEAR wa_fieldcat.
wa_fieldcat-reptext_ddic = 'Table ID'.
wa_fieldcat-fieldname = 'table_id'.
wa_fieldcat-tabname = 'lt_where_used_data_of_coll'.
wa_fieldcat-outputlen = '18'.
APPEND wa_fieldcat TO it_fieldcat.
CLEAR wa_fieldcat.
wa_fieldcat-reptext_ddic = 'Table Description'.
wa_fieldcat-fieldname = 'table_description'.
wa_fieldcat-tabname = 'lt_where_used_data_of_coll'.
wa_fieldcat-outputlen = '40'.
APPEND wa_fieldcat TO it_fieldcat.
CLEAR wa_fieldcat.
wa_fieldcat-reptext_ddic = 'Numer of Records Found'.
wa_fieldcat-fieldname = 'nr_of_records'.
wa_fieldcat-tabname = 'lt_where_used_data_of_coll'.
wa_fieldcat-outputlen = '30'.
APPEND wa_fieldcat TO it_fieldcat.
*pass data and field catalog to ALV function module
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = repid
it_fieldcat = it_fieldcat
i_structure_name = 'lty_where_used_data_of_coll'
TABLES
t_outtab = lt_where_used_data_of_coll.
'lt_where_used_data_of_coll' is my local table that I have already filled with a working function earlier in my program. This function works and I have tested it and the table fills itself with data. My next step was displaying this data to the end user. The error report I receive when executing this program is:
Short text: Field symbol has not yet been assigned.
What happened?:
Error in the ABAP Application Program.
The current ABAP program "SAPLSLVC" had to be terminated because it has
come across a statement that unfortunately cannot be executed.
Error analysis:
You attempted to access an unassigned field symbol
(data segment "-1").
Trigger Location of Runtime Error:
Program SAPLSLVC
Include LSLVCF36
Row 3,273
Module type (FORM)
Module Name FILL_DATA_TABLE
I really don't know how to start finding my mistake. It seems like it runs bad when calling a function from ABAP itself.
Any help is much appreciated.
EDIT: As was suggested I implemented another way of displaying an ALV that can be found below. This way works fine and gives no errors. Question still remains why the older method does give me an error.
I replaced the entire block of code above with this:
DATA alv TYPE REF TO cl_salv_table. DATA message TYPE REF TO cx_salv_msg.
*initialize ALV
TRY.
cl_salv_table=>factory(
IMPORTING
r_salv_table = alv
CHANGING
t_table = lt_where_used_data_of_coll ).
CATCH cx_salv_msg INTO message.
" error handling
ENDTRY.
*display ALV
alv->display( ).
why the older method does give me an error
Field catalog names are case sensitive. Capitalize every fieldname and tabname value and see if the error's still there. Also make sure that the names match those of your internal table lt_where_used_data_of_coll

How to use CRM_ORDER_READ function module in SAP CRM?

I am a fresher. Just 2 months of experience in SAP ABAP.
I am asked to get the quotation date for list of contracts. For that I need to get the crm business transaction number from everh table.
Now I need to use this transaction number in the program crm_order_read and get the export parameter et_orderadm_i in which GUID will be available and also the creation date and time(quotation date).
Now I am not able to understand that how to pass the transaction number(object_id) in the program crm_order_read? There is also a function module crm_order_id available, but there is no import parameter which is a transaction number.
Again, how the export parameter et_orderadm_i will contain the quotation date? I am not able to find a way to write the piece of code.
Usually you don't pass IDs to CRM_ORDER_READ, but GUIDs.
If you have anyhow only IDs available, you first might want to change the approach. Or make a select on table CRMD_ORDERADM_H.
Which object has which guid can be seen in SE16 => CRMD_ORDERADM_H => F8.
However you can test the function module CRM_ORDER_READ in the program SE38=>CRM_ORDER_READ also with IDs.
Here's some basic coding that you can use as template.
INCLUDE crm_object_names_con.
data:
lv_guid TYPE crmt_object_guid,
lt_guid TYPE crmt_object_guid_tab,
lt_req_obj TYPE crmt_object_name_tab,
lt_orderadm_i TYPE crmt_orderadm_i_wrkt,
ls_orderadm_i TYPE crmt_orderadm_i_wrk,
lt_orderadm_h TYPE crmt_orderadm_h_wrkt,
ls_orderadm_h TYPE crmt_orderadm_h_wrk.
CLEAR lt_guid.
INSERT lv_guid INTO TABLE lt_guid.
INSERT gc_object_name-orderadm_h INTO TABLE lt_req_obj.
INSERT gc_object_name-orderadm_i INTO TABLE lt_req_obj.
CALL FUNCTION 'CRM_ORDER_READ'
EXPORTING
it_header_guid = lt_guid
it_requested_objects = lt_req_obj
IMPORTING
et_orderadm_h = lt_orderadm_h.
et_orderadm_i = lt_orderadm_i.
READ TABLE lt_orderadm_i INTO ls_orderadm_i INDEX 1.
LOOP AT lt_orderadm_i INTO ls_orderadm_i .
ENDLOOP.
Tipps:
Double-click on CRM_ORDER_READ to navigate into it and get the exported data-types from there if you need different ones.
In CRM_ORDER_READ click on the where-used-list to see how it is implemented at other locations.
The date can be found in ORDERADM_H-POSTING_DATE.

Resources