cancel
Showing results for 
Search instead for 
Did you mean: 

Function Error occurred in class CL_RSTRAN_RUNTIME_EXE

Former Member
0 Kudos

Hi,

I am inspecting the BW system and find that the process chain occurred.The Message number is "RATRAN301" and prompts me that Division by zero in the end routine.But i find no error in the end routine.Finally i used SE91 find where the error occurred.It is the six functions "CHECK_IS_TRANSFORMABLE"、"GET_INVERSE_PROCESSING" "GET_LOG"、"IGNORE_NO_IMPLEMENTATION"、"INVOKE_INVERSE_ROUTINE"、"PREPARE_INVERSE_MAPPING" in the class CL_RSTRAN_RUNTIME_EXE.

Help me please...

The code in "CHECK_IS_TRANSFORMABLE" is

METHOD check_is_transformable.

CASE i_s_field-fieldname.

WHEN rsd_c_fieldnm_chngid OR
rsd_c_fieldnm_record OR
rsd_c_fieldnm_requid OR
rsd_c_fieldnm_datapakid OR
rsd_c_fieldnm_partno OR
rsd_c_fieldnm_recordtp OR
rsd_c_fieldnm_request OR
rsd_c_fieldnm_sid.

r_is_transformable = rs_c_false.

WHEN OTHERS.

r_is_transformable = rs_c_true.

ENDCASE.

ENDMETHOD.

The code in "GET_INVERSE_PROCESSING" is

METHOD GET_INVERSE_PROCESSING.

r_true = p_s_invers_exe-exe.

ENDMETHOD.

The code in "GET_LOG" is

METHOD get_log.

DATA:
l_r_log_component TYPE REF TO cl_rsbm_log_component.


IF i_r_log IS INITIAL.
IF me->p_r_dummy_log IS INITIAL.
CREATE OBJECT me->p_r_dummy_log TYPE lcl_dtp_log_step
EXPORTING
i_r_log = l_r_log_component
i_requid = 0
i_stepid = 0.
ENDIF.
r_r_log = me->p_r_dummy_log.
ELSE.
r_r_log = i_r_log.
ENDIF.

ENDMETHOD. "PREPARE_INVERSE_MAPPING

The code in "IGNORE_NO_IMPLEMENTATION" is

METHOD ignore_no_implementation.

STATICS s_ignore TYPE rs_bool VALUE '*'.
DATA l_value TYPE rsadmin-value.

IF s_ignore = '*'.
SELECT SINGLE value FROM rsadmin INTO l_value
WHERE object = 'RSLPO_DTP_FILTER_INVERS'.
IF sy-subrc = 0.
s_ignore = rs_c_true.
ELSE.
s_ignore = rs_c_false.
ENDIF.
ENDIF.

r_ignore = s_ignore.
ENDMETHOD.

The code in "INVOKE_INVERSE_MAPPING" is

METHOD invoke_inverse_routine.

DATA:
l_exact TYPE rs_bool,
l_th_fields_inbound TYPE rstran_t_field_inv,
l_th_fields_routine_inbound TYPE rstran_t_field_inv,
l_is_main_selection TYPE rs_bool,
l_routine_exact TYPE rs_bool,
l_r_selset_inbound TYPE REF TO cl_rsmds_set,
l_r_selset_routine_outbound TYPE REF TO cl_rsmds_set,
l_r_selset_routine_inbound TYPE REF TO cl_rsmds_set,
l_tr_sets TYPE rsmds_tr_sets, " table with all decompositions
l_r_union_set TYPE REF TO cl_rsmds_set.

FIELD-SYMBOLS:
<l_s_field> LIKE LINE OF l_th_fields_routine_inbound,
<l_s_field_1> LIKE LINE OF l_th_fields_routine_inbound.

l_exact = rs_c_true. "Let's be optimistic

" get cartesian decomposition to call inverse routine
" with simpler selection expressions
CALL METHOD i_r_selset_outbound->get_cartesian_decomposition
EXPORTING
i_reduced = rsmds_c_boolean-true
IMPORTING
e_r_set = l_r_selset_routine_outbound
e_tr_sets = l_tr_sets.
INSERT l_r_selset_routine_outbound INTO l_tr_sets INDEX 1.

" call inverse routine for each decomposition and unite the
" inbounds, pass parameters depending on i_pass_outbound_complete
l_is_main_selection = rs_c_true.
CLEAR l_th_fields_inbound.
LOOP AT l_tr_sets INTO l_r_selset_routine_outbound.
l_th_fields_routine_inbound = c_th_fields_inbound.
l_r_selset_routine_inbound = cl_rsmds_set=>get_universal_set( ).
l_routine_exact = rs_c_false.
CALL METHOD me->p_r_exe->(i_method_name)
EXPORTING
i_th_fields_outbound = i_th_fields_outbound
i_r_selset_outbound = l_r_selset_routine_outbound
i_is_main_selection = l_is_main_selection
i_r_selset_outbound_complete = i_r_selset_outbound
i_r_universe_inbound = i_r_universe_inbound
CHANGING
c_th_fields_inbound = l_th_fields_routine_inbound
c_r_selset_inbound = l_r_selset_routine_inbound
c_exact = l_routine_exact.

* IF l_th_fields_routine_inbound NE c_th_fields_inbound. "H1386037
IF l_th_fields_inbound NE l_th_fields_routine_inbound.
LOOP AT l_th_fields_routine_inbound ASSIGNING <l_s_field>.
READ TABLE l_th_fields_inbound ASSIGNING <l_s_field_1>
WITH TABLE KEY segid = <l_s_field>-segid
fieldname = <l_s_field>-fieldname.
IF sy-subrc <> 0.
INSERT <l_s_field> INTO TABLE l_th_fields_inbound.
ELSE.
IF NOT ( <l_s_field_1>-aggrgen EQ rsd_c_aggr-ini OR
<l_s_field_1>-aggrgen EQ <l_s_field>-aggrgen ).
* =
*-- If <l_s_field_1>-aggrgen NE rsd_c_aggr-ini AND
*- <l_s_field_1>-aggrgen NE <l_s_field>-aggrgen .

*-- possibly aggrgen needs to be aggregated like the following schema:
*- all other possible aggregation functions are summarized by 'OTH'

* INI + INI -> INI
* INI + NOP -> NOP
* INI + OTH -> NOP
* NOP + * -> NOP
* OTH + INI -> NOP
* OTH + NOP -> NOP
* OTH + OTH# -> OTH (for OTH = OTH#)
*- NOP (for OTH <> OTH#)

*-- currently short cut is implemented.
<l_s_field_1>-aggrgen = rsd_c_aggr-ini.
ENDIF.
ENDIF.
ENDLOOP.
ENDIF.
" evaluate exact-property of inverse routine to
" exact-property of entire transformation
IF l_routine_exact EQ rs_c_false.
l_exact = rs_c_false.
ENDIF.
IF l_is_main_selection EQ rs_c_false AND
l_r_selset_routine_inbound->is_universal( ) EQ rsmds_c_boolean-true.
DELETE l_tr_sets FROM 2.
EXIT. "Loop
ENDIF.

MODIFY l_tr_sets FROM l_r_selset_routine_inbound.
l_is_main_selection = rs_c_false.
ENDLOOP. " loop at l_tr_sets

READ TABLE l_tr_sets INTO l_r_selset_inbound INDEX 1.
TRY.
IF LINES( l_tr_sets ) GT 1.
l_r_union_set = cl_rsmds_set=>get_empty_set( ).
LOOP AT l_tr_sets INTO l_r_selset_routine_inbound FROM 2.
l_r_union_set = l_r_union_set->unite( l_r_selset_routine_inbound ).
ENDLOOP.
l_r_selset_inbound = l_r_selset_inbound->intersect( l_r_union_set ).
ENDIF.
CATCH cx_rsmds_sets_not_compatible.
" too large result set is again filtered by query processor
RETURN.
ENDTRY.

c_th_fields_inbound = l_th_fields_inbound.
c_r_selset_inbound = l_r_selset_inbound.
c_exact = l_exact.

ENDMETHOD.

The code in "PREPARE_INVERSE_MAPPING" is

METHOD prepare_inverse_mapping.

DATA:
l_s_const_selset LIKE LINE OF me->p_th_const_selsets,
l_count_rulesteps TYPE i,
l_r_data TYPE REF TO data,
l_r_dimension TYPE REF TO if_rsmds_dimension,
l_r_dimension_inbound TYPE REF TO if_rsmds_dimension,
l_r_dimension_outbound TYPE REF TO if_rsmds_dimension,
l_s_dimmapping TYPE LINE OF rsmds_th_dimmappings,
l_rx_exception TYPE REF TO cx_root,
l_th_fields_rt TYPE rsbk_th_field_rt,
l_s_field_rt LIKE LINE OF l_th_fields_rt,
l_fieldname TYPE fieldname,
l_sx_group LIKE LINE OF me->p_sx_inverse_mapping-tsx_groups,
l_s_head TYPE rstranhead,
l_r_inbound TYPE REF TO cl_rsbk_data,
l_kind TYPE rstran_time,
l_r_log LIKE i_r_log,
l_t_mapping TYPE rstran_t_mapping,
l_r_outbound TYPE REF TO cl_rsbk_data,
l_t_proxy_rule TYPE rstran_t_rule_ref,
l_t_rule TYPE rstran_t_rule,
l_s_ruleinfo TYPE rstranrule,
l_t_rulesteps TYPE rstran_t_rulestep,
l_r_segment_inbound TYPE REF TO cl_rsbk_data_segment,
l_r_segment_outbound TYPE REF TO cl_rsbk_data_segment,
l_tx_segments TYPE cl_rstran_stat=>ty_tx_rsbk,
l_r_set TYPE REF TO cl_rsmds_set,
l_t_source_fields TYPE rstran_tx_mapped_field,
l_r_step_const TYPE REF TO cl_rstran_step_constant,
l_r_step_convert TYPE REF TO cl_rstran_step_convert,
l_r_step_gen TYPE REF TO cl_rstran_gen_step_rout,
l_r_step_time TYPE REF TO cl_rstran_step_time,
l_r_structdescr TYPE REF TO cl_abap_structdescr,
l_t_target_fields TYPE rstran_tx_mapped_field,
l_r_tran TYPE REF TO cl_rstran_model,
l_r_universe_inbound TYPE REF TO cl_rsmds_universe,
l_r_universe_outbound TYPE REF TO cl_rsmds_universe.

DATA:
l_sx_rule LIKE LINE OF l_sx_group-thx_rules,
l_sx_field_outbound LIKE LINE OF l_sx_group-thx_fields_outbound.

FIELD-SYMBOLS:
<l_s_const_data> TYPE any,
<l_s_data> TYPE any,
<l_t_data> TYPE STANDARD TABLE,
<l_s_dimmapping> LIKE l_s_dimmapping,
<l_sx_group> LIKE LINE OF me->p_sx_inverse_mapping-tsx_groups,
<l_s_field_outbound> LIKE LINE OF me->p_sx_inverse_mapping-th_fields_outbound_all,
<l_sx_field_outbound> LIKE LINE OF <l_sx_group>-thx_fields_outbound,
<l_ts_knots> TYPE SORTED TABLE,
<l_knot> TYPE any,
<l_s_mapping> LIKE LINE OF l_t_mapping,
<l_sx_mapped_field> TYPE LINE OF rstran_tx_mapped_field,
<l_method_name> TYPE seocmpname,
<l_s_source_field> LIKE LINE OF l_t_source_fields,
<l_s_source_mapping> LIKE LINE OF l_t_mapping,
<l_s_rule> LIKE LINE OF l_t_rule,
<l_sx_rule> LIKE LINE OF <l_sx_group>-thx_rules,
<l_s_rulestep> LIKE LINE OF l_t_rulesteps,
<l_sx_segment> LIKE LINE OF l_tx_segments,
<l_s_field> LIKE LINE OF <l_sx_segment>-t_field,
<l_s_target_field> LIKE LINE OF l_t_target_fields,
<l_s_target_mapping> LIKE LINE OF l_t_mapping.

DATA:
l_s_field LIKE LINE OF l_sx_rule-th_fields_inbound.
DATA:
l_timestamp TYPE rstimestmp,
l_rto_timestamp TYPE rstimestmp.


IF p_check_runtime_version = rs_c_true.
SELECT SINGLE timestmp FROM rstran BYPASSING BUFFER
INTO l_timestamp
WHERE tranid = me->n_tranid
AND objvers = rs_c_objvers-active.
IF sy-subrc = 0.
IF p_trfn_timestamp < l_timestamp AND me->p_sx_inverse_mapping-tranid IS NOT INITIAL.
ASSERT me->p_sx_inverse_mapping-tranid = me->n_tranid.
CLEAR me->p_sx_inverse_mapping.
CLEAR p_trfn_timestamp.
DELETE p_tr_instances WHERE table_line = me.
DELETE gt_r_tranid WHERE tranid = me->n_tranid.
CLEAR p_r_exe. "current runtime instance
RETURN.
ENDIF.
ENDIF.
ENDIF.

IF rto_is_on( ) EQ rs_c_false.

IF me->p_sx_inverse_mapping IS INITIAL.

* get instance of transformation via factory
TRY.
l_r_tran = cl_rstran_model=>factory( me->n_tranid ).
CATCH cx_rstran_not_found
cx_rstran_input_invalid
cx_rstran_cancelled
cx_rstran_not_authorized
cx_rstran_display_only INTO l_rx_exception.
RAISE EXCEPTION TYPE cx_rs_program_error
EXPORTING
previous = l_rx_exception
method = 'PREPARE_INVERSE_MAPPING'.
ENDTRY.
me->p_sx_inverse_mapping-tranid = me->n_tranid.
CALL METHOD l_r_tran->get_header_target
IMPORTING
e_s_head = l_s_head.
me->p_sx_inverse_mapping-primary_segid_outbound = l_s_head-rootsegment.
CALL METHOD l_r_tran->get_header_source
IMPORTING
e_s_head = l_s_head.
me->p_sx_inverse_mapping-primary_segid_inbound = l_s_head-rootsegment.
l_r_universe_outbound = me->get_universe_outbound( ).
l_r_universe_inbound = me->get_universe_inbound( ).

TRY.
CALL METHOD cl_rstran_rto=>complete_inverse_mapping_model
EXPORTING
i_r_universe_outbound = l_r_universe_outbound
i_r_universe_inbound = l_r_universe_inbound
IMPORTING
c_sx_inverse_mapping = me->p_sx_inverse_mapping.
CATCH cx_rstran_error_with_message INTO l_rx_exception.
RAISE EXCEPTION TYPE cx_rs_program_error
EXPORTING
previous = l_rx_exception
method = 'PREPARE_INVERSE_MAPPING'.
ENDTRY.
ENDIF. " initial inverse mapping

ELSE.

TRY.
IF me->p_sx_inverse_mapping-tranid IS INITIAL.

CALL METHOD cl_rstran_rto=>get_inverse_mapping
EXPORTING
i_tranid = me->n_tranid
IMPORTING
e_sx_inverse_mapping = me->p_sx_inverse_mapping
e_r_universe_inbound = l_r_universe_inbound
e_r_universe_outbound = l_r_universe_outbound
e_timestamp = l_rto_timestamp.
ENDIF.
CATCH cx_rs_error.
ENDTRY.

ENDIF.
IF l_r_universe_outbound IS NOT BOUND.
*-- only outbound needed for futher processing
l_r_universe_outbound = me->get_universe_outbound( ).
ENDIF.
p_trfn_timestamp = l_timestamp. "from active version of TRFN

* Postprocessing:
*-- for temporary transformable
LOOP AT p_sx_inverse_mapping-tsx_groups ASSIGNING <l_sx_group>.
LOOP AT <l_sx_group>-thx_fields_outbound ASSIGNING <l_sx_field_outbound>
WHERE transformable = 'T'. "temporary set
CLEAR <l_sx_field_outbound>-transformable.
ENDLOOP.
ENDLOOP.

*-- for constant rules
TRY.
CREATE OBJECT l_r_outbound.

CLEAR l_s_field-aggrgen.
CALL METHOD cl_rstran_runtime_exe=>get_field_list_outbound
EXPORTING
i_tranid = me->n_tranid
IMPORTING
e_tx_field_dtp = l_tx_segments.
LOOP AT l_tx_segments ASSIGNING <l_sx_segment>.
CLEAR l_th_fields_rt.
l_s_field-segid = <l_sx_segment>-segid.
LOOP AT <l_sx_segment>-t_field ASSIGNING <l_s_field>.
MOVE-CORRESPONDING <l_s_field> TO l_s_field_rt.
INSERT l_s_field_rt INTO TABLE l_th_fields_rt.
MOVE-CORRESPONDING <l_s_field> TO l_s_field.
INSERT l_s_field INTO TABLE me->p_sx_inverse_mapping-th_fields_outbound_all.
ENDLOOP.
IF <l_sx_segment>-segid EQ me->p_sx_inverse_mapping-primary_segid_outbound.
l_r_segment_outbound = l_r_outbound->add_segment_from_fieldlist(
i_segid = <l_sx_segment>-segid
i_th_field = l_th_fields_rt ).
ENDIF.
ENDLOOP.

* Create also dummy inbound data package with an initial data record in the primary segment
* Get info from inbound

CREATE OBJECT l_r_inbound.
CLEAR l_s_field-aggrgen.
CLEAR l_tx_segments.
CALL METHOD cl_rstran_runtime_exe=>get_field_list_inbound
EXPORTING
i_tranid = me->n_tranid
IMPORTING
e_tx_field_dtp = l_tx_segments.
LOOP AT l_tx_segments ASSIGNING <l_sx_segment>.
CLEAR l_th_fields_rt.
l_s_field-segid = <l_sx_segment>-segid.
LOOP AT <l_sx_segment>-t_field ASSIGNING <l_s_field>.
MOVE-CORRESPONDING <l_s_field> TO l_s_field_rt.
INSERT l_s_field_rt INTO TABLE l_th_fields_rt.
MOVE-CORRESPONDING <l_s_field> TO l_s_field.
INSERT l_s_field INTO TABLE me->p_sx_inverse_mapping-th_fields_inbound_all.
ENDLOOP.
l_r_segment_inbound = l_r_inbound->add_segment_from_fieldlist(
i_segid = <l_sx_segment>-segid
i_th_field = l_th_fields_rt ).
ENDLOOP.

l_r_segment_inbound = l_r_inbound->get_segment( me->p_sx_inverse_mapping-primary_segid_inbound ).
l_r_data = l_r_segment_inbound->get_workarea( ).
l_r_segment_inbound->insert_workarea( l_r_data ).

CLEAR me->p_th_const_selsets.
LOOP AT me->p_sx_inverse_mapping-tsx_groups ASSIGNING <l_sx_group>.
l_s_const_selset-groupid = <l_sx_group>-groupid.
l_s_const_selset-r_selset = cl_rsmds_set=>get_universal_set( ).

IF 1 = 2. " out sourced to cl_rstran_rto=>complete_inverse_mapping_model
* Add fields with no rule as constant (initial) value
CLEAR l_s_dimmapping-dimname_to.
LOOP AT me->p_sx_inverse_mapping-th_fields_outbound_all ASSIGNING <l_s_field_outbound>
WHERE segid EQ me->p_sx_inverse_mapping-primary_segid_inbound
AND fieldname NE 'SID'. "#EC CI_HASHSEQ
READ TABLE <l_sx_group>-thx_fields_outbound
WITH TABLE KEY segid = <l_s_field_outbound>-segid
fieldname = <l_s_field_outbound>-fieldname
TRANSPORTING NO FIELDS.
IF sy-subrc NE 0 AND check_is_transformable( <l_s_field_outbound> ) = rs_c_true.
l_s_dimmapping-dimname_from = <l_s_field_outbound>-fieldname.
INSERT l_s_dimmapping INTO TABLE <l_sx_group>-s_const_rules-th_dimmappings.
ENDIF.
ENDLOOP.

ENDIF.

IF NOT <l_sx_group>-s_const_rules-th_dimmappings IS INITIAL.

l_r_segment_outbound->set_fieldattr(
i_fieldname = '*'
i_not_requested = rs_c_true ).
LOOP AT <l_sx_group>-s_const_rules-th_dimmappings ASSIGNING <l_s_dimmapping>.
l_fieldname = <l_s_dimmapping>-dimname_from.
l_r_segment_outbound->set_fieldattr(
i_fieldname = l_fieldname
i_not_requested = rs_c_false ).
ENDLOOP.
l_r_outbound->clear_data( ).

l_r_log = me->get_log( i_r_log ).
*-- get only the constant value and suppress all other rule types
p_s_invers_exe-constant = rs_c_true.
CALL METHOD me->transform
EXPORTING
i_r_inbound = l_r_inbound
i_r_log = l_r_log
IMPORTING
e_r_outbound = l_r_outbound.
p_s_invers_exe-constant = rs_c_false.

l_r_data = l_r_segment_outbound->get_data( ).
ASSIGN l_r_data->* TO <l_t_data>.
READ TABLE <l_t_data> ASSIGNING <l_s_data> INDEX 1.
ASSERT sy-subrc EQ 0.

LOOP AT <l_sx_group>-s_const_rules-th_dimmappings ASSIGNING <l_s_dimmapping>.
TRY.
l_r_dimension = l_r_universe_outbound->get_dimension_by_name( <l_s_dimmapping>-dimname_from ).
l_r_data = l_r_dimension->create_table_ref( ).
ASSIGN l_r_data->* TO <l_ts_knots>.
ASSIGN COMPONENT <l_s_dimmapping>-dimname_from OF STRUCTURE <l_s_data> TO <l_knot>.
ASSERT sy-subrc EQ 0.
APPEND <l_knot> TO <l_ts_knots>.
l_r_set = l_r_dimension->create_set( i_knots = <l_ts_knots> ).
l_s_const_selset-r_selset = l_s_const_selset-r_selset->intersect( l_r_set ).
CATCH cx_rsmds_input_invalid
cx_rsmds_input_invalid_type
cx_rsmds_sets_not_compatible INTO l_rx_exception.
RAISE EXCEPTION TYPE cx_rs_program_error
EXPORTING
previous = l_rx_exception
method = 'PREPARE_INVERSE_MAPPING'.
ENDTRY.
ENDLOOP.

ENDIF.

INSERT l_s_const_selset INTO TABLE me->p_th_const_selsets.
ENDLOOP.

CATCH cx_rs_not_found
cx_rs_step_failed
cx_rsmds_input_invalid
cx_rsmds_input_invalid_type
cx_rsmds_sets_not_compatible INTO l_rx_exception.

RAISE EXCEPTION TYPE cx_rs_program_error
EXPORTING
previous = l_rx_exception
method = 'PREPARE_INVERSE_MAPPING'.

ENDTRY.

ENDMETHOD. "PREPARE_INVERSE_MAPPING

Accepted Solutions (0)

Answers (0)