cancel
Showing results for 
Search instead for 
Did you mean: 

Searching for generic approach using classes in Bi Transformation Routines

dirk_meyer2
Explorer

Hi Abap OO Pros,

I have been trying to create a OO Class for usage in an endroutine of a BI transformation. There are some papers and discussions on it I have been working through and I found two concepts

1. Loop at result package and call the Method in each loop.

2. Move the Result pack to the Class and chang it.

For that approach I got some questions:

- Is there a performance difference.

I wondered because the logic is the same just at different places

- Generic usage The discussions state that for the transfer of the data a type according to the Result Package has to be created. This would be for me a no go since that would prohibit a generic usage. Therefore I have been starting to try to find a generic solution in that way:

Method parameter: Result_Pack Changing type Standard table.

Method coding:

FIELD-SYMBOLS: <rs> type table,
......

CREATE DATA lt_trg TYPE STANDARD TABLE OF (l_trg_tab).

ASSIGN lt_trg->* to <rs>.


LOOP at result_pack ASSIGNING <rs>.


  LOOP at result_pack ASSIGNING <rs>.
    READ TABLE gt_MDCOFPR ASSIGNING <MDCOFPR>
    WITH KEY
    /BIC/C1FINPRIO =  <rs>-/BIC/C0FINPRIO.

<rs>-fiscper = <MDCOFPR>-fiscper.
<rs>-fiscper3 = <MDCOFPR>-fiscper3.
<rs>-fiscyear = <MDCOFPR>-fiscyear.

  ENDLOOP.

The var (l_trg_tab) I derive based on the parameter entry for the target name of the Trafo.

The Code Check then claims that <RS> does not have the field <rs>-/BIC/C0FINPRIO.

I have been working with variable in standard programs. There an error popped up, too. But I could ignore it and the program would run.

In this case it would dump right when the routine would hit "create object ".

Since my OO knowledge is really basic I have the hope that either I made a mistake or there is an other approach.

Anybody has experience with that and can help?
(Maybe this approach has no advantages at all.

The I would stick to nr. 1

Thanks for

Help Dirk

Accepted Solutions (0)

Answers (2)

Answers (2)

matt
Active Contributor

I think moving the working code of routines right out of the transformation is a good idea - not only does it mean you can change the code without having to reactivate the transformation, but it also gives you full version management. It's the approach I've followed for the past ten years or so of developing in BW.

For your example, there are three fields that need to be accessed, FISCPER, FISCPER3 and FISCYEAR. This is how I would write it.

DATA: begin of fields_of_interest,
        /bic/c0finprio TYPE /bic/oic0finprio,
      end of fields_of_interest.

FIELD-SYMBOLS: <record> TYPE ANY.
LOOP AT result_pack ASSIGNING <record>.
  MOVE-CORRESPONDING <record> TO fields_of_interest.
  READ TABLE gt_mdcofpr ASSIGNING <mdocfpr> WITH TABLE KEY /bic/c1finprio =         fields_of_interest-/bic/c1finprio.
  CHECK sy-subrc IS INITIAL.
  MOVE-CORRESPONDING <mdocfpr> TO <record>.
ENDLOOP.

1) Table gt_mdcofpr should be defined something like HASHED WITH UNIQUE-KEY /bic/clfinprio.

2) This assumes that table gt_mdcofpr only has fields fiscper, fiscper3, fiscyear in common with the results. if not, then do something like this.

DATA: begin of fields_of_interest,
        /bic/c0finprio TYPE /bic/oic0finprio,
        fiscper TYPE /bi0/fiscper,
        fiscper3 TYPE /bi0/fiscper3,
        fiscyear TYPE /bi0/fiscyear,
      end of fields_of_interest.

FIELD-SYMBOLS: <record> TYPE ANY.
LOOP AT result_pack ASSIGNING <record>.
  MOVE-CORRESPONDING <record> TO fields_of_interest.
  READ TABLE gt_mdcofpr ASSIGNING <mdocfpr> WITH TABLE KEY /bic/c1finprio =         fields_of_interest-/bic/c1finprio.
  CHECK sy-subrc IS INITIAL.
  MOVE-CORRESPONDING <mdocfpr> TO fields_of_interest.
  MOVE-CORRESPONDING fields_of_interest TO <record>.
ENDLOOP.
dirk_meyer2
Explorer
0 Kudos

Hi Matthew,

Thanks for reply. This is how I made it the last 10 years, too.
Thouigh in the last 2 years and especially with a recent (SBO to BI) project I found my self copying the same code in multiple trafos. I have used MF in a way that I habe cut out the logic inside of the loop.

With an increasing usage of OO by externals I started to change the horse just to keep up.

So the code thats working fine at the moment is below, where the tabel read is in a constructor and the derivation of the 3 fields a public method.

Despite some fickle behaviour with testing it is at the end nicely structured. Maybe more click-a-di-click if you do not use the line mode.

Advantage is that i can group n reoccuring logics as methods in one project specific or even cross project class.

DATA: LO_ZCL_COVER_LOOKUP_001 TYPE REF TO ZCL_COVER_LOOKUP_001,
      L_C0ZSYSID type c LENGTH 4,
      t_filter_values type RSBK_TH_RANGE,
      l_filter_values like line of t_filter_values.

t_filter_values = p_r_request->GET_TH_RANGE( ).
read table t_filter_values into l_filter_values with key
FIELDNM = 'C0ZSYSID'.

IF SY-SUBRC = 0.
 L_C0ZSYSID = l_filter_values-LOW.
ENDIF.

create object LO_ZCL_COVER_LOOKUP_001
EXPORTING
P_C0ZSYSID  = L_C0ZSYSID
P_GET_FP = 'X'.

LOOP at RESULT_PACKAGE ASSIGNING <result_fields>.

CALL METHOD LO_ZCL_COVER_LOOKUP_001->GET_FISCPER
EXPORTING
I_FINNCPRIO = <result_fields>-/BIC/C1FINPRIO
I_C0ZSYSID  = <result_fields>-/BIC/C0ZSYSID
importing
E_FISCPER  = <result_fields>-FISCPER
E_FISCPER3 = <result_fields>-FISCPER3
E_FISCYEAR = <result_fields>-FISCYEAR
    .
ENDLOOP.


Maybe I was a bit unclear above.

My aim is to reduce the code even more and get the complete Result Package loop into the Class,
without having to tailor the class to one specific Transformation.
For that I would have to define Result Package as Changing one single time for all methods.
I am aware that this rather works for standard bread and butter logics but woud be still a first step.

Cheers Dirk

Sandra_Rossi
Active Contributor

Externalizing code into a class pool also allows writing ABAP Unit tests!

matt
Active Contributor
0 Kudos

I'm not totally clear of your requirement, but maybe this will help. I specify the parameter for the results as CHANGING TYPE STANDARD TABLE. The only code in my end routine would be:

IF routine IS NOT BOUND.
  routine = new ZCL_MY_CLASS( ).
ENDIF.

routine->process( CHANGING x_results = RESULT_PACKAGE ).

The object reference routine is defined in the global data of the end routine class.

dirk_meyer2
Explorer
0 Kudos

Solved with the help of a super kind consultant.....


For all that are interessted:

Trafo Endroutine with FDCSDD2 as DSO name .

This is rather prototypish since, if usingInfosources, ya-man SLA++ stylie in full effect, they need to be 1:1 with the DSO.
But with the advent of HANA this is here rather about own skill rather than necessity.

create object LO_ZCL_COVER_LOOKUP
EXPORTING
p_target = 'FDCSDD2'
P_C0ZSYSID  = L_C0ZSYSID
P_GET_FP = 'X'.

 CALL METHOD LO_ZCL_COVER_LOOKUP->GET_FISCPER
  CHANGING
    RESULT_PACK = RESULT_PACKAGE.


The method is:

data: ls_trg TYPE REF TO data,
      l_C1FINPRIO type /BIC/OIC1FINPRIO.

* This needs to be dynamic based on name of target Infoprovider
* Definntion des fFeldes

  FIELD-SYMBOLS: <rs> type any,
                 <MDCOFPR>  type /BIC/AMDCOFPR00,
                 <C1FINPRIO> type any,
                 <FISCPER> type any,
                 <FISCPER3> type any,
                 <FISCYEAR> type any,
                 <C0ZSYSID> type any.
CREATE DATA ls_trg TYPE (l_trg_tab).

ASSIGN ls_trg->* to <rs>.
  LOOP at result_pack ASSIGNING <rs>.

**!!!! This was the missing bit
ASSIGN COMPONENT '/BIC/C1FINPRIO' of structure <rs> to <C1FINPRIO>.
if sy-subrc = 0.
 l_C1FINPRIO = <C1FINPRIO>.
endif.

ASSIGN COMPONENT '/BIC/C0ZSYSID' of structure <rs> to <C0ZSYSID>.
    READ TABLE gt_MDCOFPR ASSIGNING <MDCOFPR>
    WITH KEY
    /BIC/C1FINPRIO =  <C1FINPRIO>
    /BIC/C0ZSYSID =   <C0ZSYSID>.

if sy-subrc = 0.

**!!!! This was the missing bit
ASSIGN COMPONENT 'FISCPER' of structure <rs> to <FISCPER>.
ASSIGN COMPONENT 'FISCPER3' of structure <rs> to <FISCPER3>.
ASSIGN COMPONENT 'FISCYEAR' of structure <rs> to <FISCYEAR>.

<FISCPER>  = <MDCOFPR>-fiscper.
<FISCPER3> = <MDCOFPR>-fiscper3.
<FISCYEAR> = <MDCOFPR>-fiscyear.

ENDIF.
  ENDLOOP.

Every field that is adressed within teh dynamic tabel "naturally" (silly me;-) has to be assigned to.

This happens with the "<xyz> type any" in coop the "Assigning component 'abc' of structure <> to "<xyz> ".
It seems at the first load slower that the method called with in the cube wo I will continue with some fine tuning regarding table def. etc.

Cheers Dirk