Dynamic table type declaration - dynamic

I need to write a FM where I will receive the data type of an element as a string parameter and I would like to declare it like:
DATA: lt_test TYPE TABLE OF (iv_data_type).
where the iv_data type whould be the received type.

You should create your internal table dynamically:
DATA lt_test type ref to data.
FIELD-SYMBOLS: <lts_test> type standard table.
CREATE DATA lt_test type (iv_data_type).
ASSIGN lt_test->* to <lts_test>.
CALL FUNCTION 'TEXT_CONVERT_CSV_TO_SAP'
EXPORTING
I_TAB_RAW_DATA = lt_raw_data
TABLES
I_TAB_CONVERTED_DATA = <lts_table>
EXCEPTIONS
CONVERSION_FAILED = 1
OTHERS = 2.

you can try the following
DATA : lo_struct_des TYPE REF TO cl_abap_structdescr,
lo_result_struct TYPE REF TO cl_abap_structdescr.
DATA: lo_new_tab TYPE REF TO cl_abap_tabledescr .
DATA: lt_struct_tab TYPE abap_component_tab.
DATA: tab TYPE REF TO data,
line TYPE REF TO data.
FIELD-SYMBOLS: <fs_data> TYPE ANY TABLE,
<fs_line> TYPE any.
lo_struct_des ?= cl_abap_typedescr=>describe_by_name( 'your_Structure_name_here' ).
lt_struct_tab = lo_struct_des->get_components( ) .
lo_result_struct = cl_abap_structdescr=>create( p_components = lt_struct_tab ) .
lo_new_tab = cl_abap_tabledescr=>create( p_line_type = lo_result_struct
p_table_kind = cl_abap_tabledescr=>tablekind_std
p_unique = abap_false ).
CREATE DATA tab TYPE HANDLE lo_new_tab.
CREATE DATA line TYPE HANDLE lo_result_struct .
ASSIGN tab->* TO <fs_data>.
ASSIGN line->* TO <fs_line> .

Related

Total and subtotals problem in Export Excel from ALV tree

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."

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

Type mismatch when calling cl_salv_bs_runtime_info=>get_data_ref()

I found a solution here which I try to apply.
cl_salv_bs_runtime_info=>set(
EXPORTING
display = abap_false
metadata = abap_false
data = abap_true
).
SUBMIT ('RM07MLBS')
AND RETURN.
DATA: lt_outtab TYPE STANDARD TABLE OF alv_t_t2.
FIELD-SYMBOLS: <lt_outtab> like lt_outtab.
DATA lo_data TYPE REF TO data.
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.
Source: http://zevolving.com/2015/07/salv-table-22-get-data-directly-after-submit/
But this does not work. I get a type mismatch error in this line:
ASSIGN lo_data->* to <lt_outtab>.
What could be wrong?
Is there a way to do this generic? At runtime I don't know which report is to be called.
My overall goal is to get the report in XML or JSON format.
With the help of the answer of user mkysoft, this is the working solution, which exports the data in json format:
FUNCTION /Z_FOO/CALL_REPORT_XML.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*" EXPORTING
*" VALUE(EV_RESULT_JSON) TYPE STRING
*"----------------------------------------------------------------------
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 ('RM07MLBS')
WITH WERKS = '0557'
AND RETURN.
" get data from SALV model
cl_salv_bs_runtime_info=>get_data_ref(
IMPORTING
r_data = lo_data
).
field-SYMBOLS <lv_data> type any table.
ASSIGN lo_data->* TO <lv_data>.
ev_result_json = /ui2/cl_json=>serialize( data = <lv_data> pretty_name = /ui2/cl_json=>pretty_mode-low_case ).
cl_salv_bs_runtime_info=>clear_all( ).
ENDFUNCTION.
This helped me to get it done: https://blogs.sap.com/2011/07/07/gain-programmatic-access-to-data-of-sapgui-alv-reports/
I added dynamic table, line and component to your code for creating working example.
REPORT zmky_catch_report.
DATA: lo_data TYPE REF TO data,
lr_structdescr TYPE REF TO cl_abap_structdescr,
lr_tabledescr TYPE REF TO cl_abap_tabledescr,
ls_component TYPE abap_compdescr .
FIELD-SYMBOLS: <fs_table> TYPE table,
<fs_line> TYPE any,
<fs_field> TYPE any.
" Let know the model
cl_salv_bs_runtime_info=>set(
EXPORTING
display = abap_false
metadata = abap_false
data = abap_true
).
SUBMIT ('RM07MLBS')
AND RETURN.
TRY.
" get data from SALV model
cl_salv_bs_runtime_info=>get_data_ref(
IMPORTING
r_data = lo_data
).
lr_tabledescr ?= cl_abap_tabledescr=>describe_by_data_ref( lo_data ).
lr_structdescr ?= lr_tabledescr->get_table_line_type( ).
* Table header
WRITE 'ROWNUM '.
LOOP AT lr_structdescr->components INTO ls_component.
WRITE ls_component-name.
ENDLOOP.
ULINE.
* Lines
ASSIGN lo_data->* TO <fs_table>.
LOOP AT <fs_table> ASSIGNING <fs_line>.
WRITE sy-tabix.
LOOP AT lr_structdescr->components INTO ls_component.
ASSIGN COMPONENT ls_component-name OF STRUCTURE <fs_line> TO <fs_field>.
WRITE <fs_field>.
ENDLOOP.
WRITE /.
ENDLOOP.
CATCH cx_salv_bs_sc_runtime_info.
ENDTRY.

Filter CHANGED_AT from CRM_ORDER_READ

I have a requirement wherein I have to filter CHANGED_AT from CRM_ORDER_READ.
I used the dynamic query as follows:
lr_core = cl_crm_bol_core=>get_instance( ).
lr_core->load_component_set( 'ONEORDER' ).
lr_qs ?= cl_crm_bol_dquery_service=>get_instance( 'BTQSrvOrd' ).
lr_qs->set_query_parameters( lt_param ).
lr_qs->ADD_SELECTION_PARAM( iv_attr_name = 'CHANGED_AT'
iv_sign = 'I'
iv_option = 'GT'
iv_low = '20171127000000' ).
lr_result = lr_qs->get_query_result( ).
But the result is null though there are entries.
I found the blogs regarding the same issue but none solved the issue. Is the query correct?
Or is there any other way to filter CHANGED_AT?
Complete Code:
*"----------------------------------------------------------------------
INCLUDE: ztest_rfc_incl,
crm_object_kinds_con,
crm_object_names_con.
TYPES:
BEGIN OF ty_but000,
name_org1 TYPE bu_nameor1,
name_org2 TYPE bu_nameor2,
partner_guid TYPE bu_partner_guid,
END OF ty_but000,
BEGIN OF ty_tickets,
guid TYPE crmt_object_guid,
object_id TYPE crmt_object_id,
END OF ty_tickets,
BEGIN OF ty_ibint,
instance TYPE ib_instance,
descr TYPE ib_inst_descr,
END OF ty_ibint.
FIELD-SYMBOLS: <f_guid> TYPE crmt_object_guid,
<f_result> TYPE znasm_workorders,
<f_items_result> TYPE znasm_workorderitems,
<f_data> TYPE any,
<f_but000> TYPE ty_but000,
<f_ticket> TYPE ty_tickets,
<f_ibint> TYPE ty_ibint.
FIELD-SYMBOLS: <f_orderadm_h> TYPE crmt_orderadm_h_wrk,
<f_orderadm_i> TYPE crmt_orderadm_i_wrk,
<f_higher_item> TYPE crmt_orderadm_i_wrk,
<f_sales> TYPE crmt_sales_wrk,
<f_customer_h> TYPE crmt_customer_h_wrk,
<f_customer_i> TYPE crmt_customer_i_wrk,
<f_appointment> TYPE crmt_appointment_wrk,
<f_text> TYPE crmt_text_wrk,
<f_lines> TYPE tline,
<f_schedlin> TYPE crmt_schedlin_wrk,
<f_partner> TYPE crmt_partner_external_wrk,
<f_service_os> TYPE crmt_srv_osset_wrk,
<f_refobj> TYPE crmt_refobj_wrk,
<f_status> TYPE crmt_status_wrk,
<f_status_h> TYPE crmt_status_h_wrk,
<f_schedlin_i> TYPE crmt_schedlin_i_wrk,
<f_doc_flow> TYPE crmt_doc_flow_wrk.
DATA:
lt_status_filter TYPE rsdsselopt_t,
ls_status_filter TYPE rsdsselopt,
lt_header_guids TYPE crmt_object_guid_tab,
lt_requested_objects TYPE crmt_object_name_tab,
lr_dref TYPE REF TO data,
lv_log_handle TYPE balloghndl,
lv_or_flag TYPE boolean,
lv_cnt TYPE i,
lt_attachments TYPE zsm_attachments_tab,
ls_attachments TYPE zsm_attachments.
DATA:
lt_ibint TYPE TABLE OF ty_ibint,
lt_but000 TYPE TABLE OF ty_but000,
lt_tickets TYPE TABLE OF ty_tickets,
lt_orderadm_h TYPE crmt_orderadm_h_wrkt,
lt_opport_h TYPE crmt_opport_h_wrkt,
lt_orderadm_i TYPE crmt_orderadm_i_wrkt,
lt_sales TYPE crmt_sales_wrkt,
lt_customer_h TYPE crmt_customer_h_wrkt,
lt_customer_i TYPE crmt_customer_i_wrkt,
lt_appointment TYPE crmt_appointment_wrkt,
lt_text TYPE crmt_text_wrkt,
lt_schedlin TYPE crmt_schedlin_wrkt,
lt_partner TYPE crmt_partner_external_wrkt,
lt_shipto TYPE crmt_partner_external_wrkt,
lt_refobj TYPE crmt_refobj_wrkt,
lt_status TYPE crmt_status_wrkt,
lt_status_temp TYPE crmt_status_wrkt,
lt_schedlin_i TYPE crmt_schedlin_i_wrkt,
lt_doc_flow TYPE crmt_doc_flow_wrkt.
*-----------------------------------------------------------
" Create the filter query
*-----------------------------------------------------------
lr_core = cl_crm_bol_core=>get_instance( ).
lr_core->load_component_set( 'ONEORDER' ).
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = iv_ship_to
IMPORTING
output = iv_ship_to.
*Get and prepare dynamic query service.
lr_qs ?= cl_crm_bol_dquery_service=>get_instance( 'BTQSrvOrd' ).
IF lr_qs IS NOT INITIAL.
*build object id query
PERFORM add_to_selection_param USING it_order
'OBJECT_ID'
CHANGING lr_qs
lv_query_exists.
***status query build
lt_status_filter = it_status.
* Filter on open and in progress orders
IF it_status IS INITIAL."
MOVE 'E0002ZRPM_H' TO ls_status_filter-low. "Pending Customer
MOVE 'I' TO ls_status_filter-sign.
MOVE 'EQ' TO ls_status_filter-option.
APPEND ls_status_filter TO lt_status_filter.
MOVE 'E0003ZRPM_H' TO ls_status_filter-low. "Requires Approval
MOVE 'I' TO ls_status_filter-sign.
MOVE 'EQ' TO ls_status_filter-option.
APPEND ls_status_filter TO lt_status_filter.
MOVE 'E0009ZRPM_H' TO ls_status_filter-low. "PM In Progress
MOVE 'I' TO ls_status_filter-sign.
MOVE 'EQ' TO ls_status_filter-option.
APPEND ls_status_filter TO lt_status_filter.
ENDIF.
PERFORM add_to_selection_param USING lt_status_filter
'STATUS_COMMON'
CHANGING lr_qs
lv_query_exists.
*date query build
PERFORM add_to_selection_param USING it_date_range
'POSTING_DATE' "'DATE_RANGE'
CHANGING lr_qs
lv_query_exists.
*build ship to party queries
PERFORM add_to_selection_param USING it_ship_to
'BU_PARTNER'
CHANGING lr_qs
lv_query_exists.
PERFORM add_to_selection_param USING it_sold_to
'SOLD_TO_PARTY'
CHANGING lr_qs
lv_query_exists.
*build assigned to queries
PERFORM add_to_selection_param USING it_assigned_to
'CREATED_BY'
CHANGING lr_qs
lv_query_exists.
PERFORM add_to_selection_param USING it_territory
'SERVICE_ORG'
CHANGING lr_qs
lv_query_exists.
PERFORM add_to_selection_param USING it_process_type
'PROCESS_TYPE'
CHANGING lr_qs
lv_query_exists.
ELSE.
RETURN.
ENDIF.
CHECK lv_query_exists EQ abap_true.
* Set Query Parameters.
IF iv_max_hits IS NOT INITIAL.
ls_param-name = 'MAX_HITS'.
ls_param-value = iv_max_hits.
APPEND ls_param TO lt_param.
ENDIF.
lr_qs->set_query_parameters( lt_param ).
lr_qs->ADD_SELECTION_PARAM( iv_attr_name = 'CHANGED_AT'
iv_sign = 'I'
iv_option = 'GT'
iv_low = '20171127000000' ).
*Execute Query and retrieve result
lr_result = lr_qs->get_query_result( ).
*
CHECK lr_result IS BOUND.
*Use Iterator to access entities in query result
lr_iter ?= lr_result->get_iterator( ).
*
* Get the first record from Collection.
lr_entity = lr_iter->get_first( ).
WHILE lr_entity IS BOUND.
*Access Attributes of Business object.
* lv_object_id_fm = lr_entity->get_property_as_string( 'OBJECT_ID' ).
IF ( lr_entity->get_property_as_string( 'CONCATSTATUSER' ) EQ 'PM Complete'
OR lr_entity->get_property_as_string( 'CONCATSTATUSER' ) EQ 'Cancelled' )." and ( sy-uname ne 'HASAXENA.EXT' ).
lr_entity = lr_iter->get_next( ).
CONTINUE.
ENDIF.
lr_dref = lr_entity->get_property( 'GUID' ).
ASSIGN lr_dref->* TO <f_guid>.
INSERT <f_guid> INTO TABLE lt_header_guids.
APPEND INITIAL LINE TO et_result ASSIGNING <f_result>.
lr_dref = lr_entity->get_property( 'OBJECT_ID' ).
ASSIGN lr_dref->* TO <f_data>.
<f_result>-workorder = <f_data>.
lr_dref = lr_entity->get_property( 'SOLD_TO_PARTY' ).
ASSIGN lr_dref->* TO <f_data>.
<f_result>-kunnr = <f_data>.
lr_dref = lr_entity->get_property( 'CONTACT_PERSON' ).
ASSIGN lr_dref->* TO <f_data>.
<f_result>-contact = <f_data>.
lr_dref = lr_entity->get_property( 'SOLD_TO_PARTY_LIST' ).
ASSIGN lr_dref->* TO <f_data>.
<f_result>-sold_party_name = <f_data>.
lr_dref = lr_entity->get_property( 'NET_VALUE' ).
ASSIGN lr_dref->* TO <f_data>.
<f_result>-price = <f_data>.
lr_dref = lr_entity->get_property( 'PROCESS_TYPE' ).
ASSIGN lr_dref->* TO <f_data>.
<f_result>-type = <f_data>.
lr_dref = lr_entity->get_property( 'CREATED_BY' ).
ASSIGN lr_dref->* TO <f_data>.
<f_result>-assignedto = <f_data>.
lr_dref = lr_entity->get_property( 'SERVICE_ORG' ).
ASSIGN lr_dref->* TO <f_data>.
<f_result>-territory = <f_data>.
lr_dref = lr_entity->get_property( 'PO_NUMBER_SOLD' ).
ASSIGN lr_dref->* TO <f_data>.
<f_result>-customer_po = <f_data>.
lr_dref = lr_entity->get_property( 'VALID_FROM' ).
ASSIGN lr_dref->* TO <f_data>.
<f_result>-startdate = <f_data>.
lr_dref = lr_entity->get_property( 'VALID_TO' ).
ASSIGN lr_dref->* TO <f_data>.
<f_result>-enddate = <f_data>.
lr_entity = lr_iter->get_next( ).
ENDWHILE.
*-----------------------------------------------------------
" Read additional data for result list
*-----------------------------------------------------------
IF lt_header_guids IS NOT INITIAL.
* fill internal tables
INSERT gc_object_name-orderadm_h INTO TABLE lt_requested_objects.
INSERT gc_object_name-orderadm_i INTO TABLE lt_requested_objects.
INSERT gc_object_name-status INTO TABLE lt_requested_objects.
INSERT gc_object_name-partner INTO TABLE lt_requested_objects.
INSERT gc_object_name-doc_flow INTO TABLE lt_requested_objects.
INSERT gc_object_name-refobj INTO TABLE lt_requested_objects.
INSERT gc_object_name-schedlin INTO TABLE lt_requested_objects.
INSERT gc_object_name-schedlin_i INTO TABLE lt_requested_objects.
INSERT gc_object_name-appointment INTO TABLE lt_requested_objects.
INSERT gc_object_name-texts INTO TABLE lt_requested_objects.
INSERT gc_object_name-sales INTO TABLE lt_requested_objects.
INSERT gc_object_name-customer_i INTO TABLE lt_requested_objects.
INSERT gc_object_name-customer_h INTO TABLE lt_requested_objects.
CALL FUNCTION 'CRM_ORDER_READ'
EXPORTING
it_header_guid = lt_header_guids
iv_mode = 'C'
it_requested_objects = lt_requested_objects
iv_only_spec_items = iv_header_only
iv_no_auth_check = 'X'
IMPORTING
et_orderadm_h = lt_orderadm_h
et_orderadm_i = lt_orderadm_i
et_sales = lt_sales
et_customer_h = lt_customer_h
et_customer_i = lt_customer_i
et_appointment = lt_appointment
et_text = lt_text
et_schedlin = lt_schedlin
et_partner = lt_partner
et_refobj = lt_refobj
et_status = lt_status
et_schedlin_i = lt_schedlin_i
et_doc_flow = lt_doc_flow
CHANGING
cv_log_handle = lv_log_handle
EXCEPTIONS
document_not_found = 1
error_occurred = 2
document_locked = 3
no_change_authority = 4
no_display_authority = 5
no_change_allowed = 6
OTHERS = 7.
ENDIF.
FORM add_to_selection_param USING p_selopt TYPE rsdsselopt_t
VALUE(p_attr_name)
CHANGING lr_qs TYPE REF TO cl_crm_bol_dquery_service
p_query_exists TYPE boolean.
FIELD-SYMBOLS: <f_selopt> TYPE rsdsselopt.
DATA: lv_low TYPE string,
lv_high TYPE string.
LOOP AT p_selopt ASSIGNING <f_selopt>.
IF <f_selopt>-low IS NOT INITIAL.
lv_low = <f_selopt>-low.
lv_high = <f_selopt>-high.
* *Add selected parameters or criteria .
lr_qs->add_selection_param( iv_attr_name = p_attr_name
iv_sign = <f_selopt>-sign
iv_low = lv_low
iv_option = <f_selopt>-option
iv_high = lv_high ).
p_query_exists = abap_true.
ENDIF.
ENDLOOP.
ENDFORM.
Maybe it is because of the data type?
instead of
FIELD-SYMBOLS: <f_selopt> TYPE rsdsselopt.
DATA: lv_low TYPE string,
lv_high TYPE string.
maybe try
FIELD-SYMBOLS: <f_selopt> TYPE rsdsselopt.
DATA: lv_low TYPE comt_changed_at_usr,
lv_high TYPE comt_changed_at_usr.

Dynamically defined variable in ABAP

Lets say I have a variable (char30) which contains a name of a Datatype and I would like to create another variable of this Datatype.
Example:
lv_type = 'BU_PARTNER'
data: rt_value type range of ( lv_type ).
Any tips how to achieve this in ABAP?
Thanks!
RANGE table is just a STANDARD table with component like 'LOW', 'HIGH', 'EQ' and 'OPTION'.
Using RTTS related API to create such a STANDARD table.
data:
lr_data type ref to data,
lt_ra_string type range of string,
ls_ra_string like line of lt_ra_string,
ls_component type line of abap_component_tab,
lt_component type abap_component_tab,
lt_ra_components type abap_component_tab,
lo_struc_descr type ref to cl_abap_structdescr,
lo_table_descr type ref to cl_abap_tabledescr,
lo_data_descr type ref to cl_abap_datadescr.
field-symbols:
<lv_value> type any,
<lt_ra_type> type standard table,
<ls_ra_type> type any.
data(lv_type) = 'BU_PARTNER'.
create data lr_data type (lv_type).
lo_struc_descr ?= cl_abap_structdescr=>describe_by_data( p_data = ls_ra_string ).
lt_component = lo_struc_descr->get_components( ).
lo_data_descr ?= cl_abap_elemdescr=>describe_by_name( lv_type ).
lt_ra_components = value #( for comp in lt_component (
name = comp-name
type = cond #(
when comp-name eq 'SIGN'
or comp-name eq 'OPTION'
then comp-type
else lo_data_descr )
) ).
lo_struc_descr ?= cl_abap_structdescr=>create( lt_ra_components ).
lo_table_descr ?= cl_abap_tabledescr=>create( lo_struc_descr ).
create data lr_data type handle lo_table_descr.
assign lr_data->* to <lt_ra_type>.
create data lr_data like line of <lt_ra_type>.
assign lr_data->* to <ls_ra_type>.
assign component 'SIGN' of structure <ls_ra_type> to <lv_value>.
<lv_value> = 'I'.
assign component 'OPTION' of structure <ls_ra_type> to <lv_value>.
<lv_value> = 'EQ'.
assign component 'LOW' of structure <ls_ra_type> to <lv_value>.
<lv_value> = 'DUMMY1'.
assign component 'HIGH' of structure <ls_ra_type> to <lv_value>.
<lv_value> = 'DUMMY2'.
* <lt_ra_type> is your range table
append <ls_ra_type> to <lt_ra_type>.
A range data type is nothing but a structure with four fields :
Sign
Option
Low
High
So you can use RTTS to build such a structure dynamically since the data types for sign and option are fixed and the ones for 'low" and "high" you can set dynamically . Then once you have the structure object reference, you can assign it to a field symbol.
As far as I know, there's no built-in command for creating range tables dynamically. You have to use RTTC to build up the range table:
TYPE-POOLS: abap.
DATA:
g_dataelement TYPE rollname,
go_structdescr TYPE REF TO cl_abap_structdescr,
go_tabledescr TYPE REF TO cl_abap_tabledescr,
gt_component TYPE abap_component_tab,
gs_component TYPE LINE OF abap_component_tab,
gr_range TYPE REF TO data,
gr_range_line TYPE REF TO data.
FIELD-SYMBOLS: <gs_range_line> TYPE any,
<gs_range> TYPE table.
START-OF-SELECTION.
g_dataelement = 'BU_PARTNER'.
" Create component table
gs_component-name = 'SIGN'.
gs_component-type ?= cl_abap_elemdescr=>get_c( 1 ).
INSERT gs_component INTO TABLE gt_component.
gs_component-name = 'OPTION'.
gs_component-type ?= cl_abap_elemdescr=>get_c( 2 ).
INSERT gs_component INTO TABLE gt_component.
gs_component-name = 'LOW'.
gs_component-type ?= cl_abap_elemdescr=>describe_by_name( g_dataelement ).
INSERT gs_component INTO TABLE gt_component.
gs_component-name = 'HIGH'.
gs_component-type ?= cl_abap_elemdescr=>describe_by_name( g_dataelement ).
INSERT gs_component INTO TABLE gt_component.
" Create type descriptors
go_structdescr ?= cl_abap_structdescr=>create( gt_component ).
go_tabledescr ?= cl_abap_tabledescr=>create( go_structdescr ).
" Create usable variables
CREATE DATA gr_range TYPE HANDLE go_tabledescr.
ASSIGN gr_range->* TO <gs_range>.
CREATE DATA gr_range_line TYPE HANDLE go_structdescr.
ASSIGN gr_range_line->* TO <gs_range_line>.