Conditional loop clearing of HR infotype itab lines?

1.2k views Asked by At

I have no idea about ABAP, but my colleague (also no idea about it) showed me some code he came up with and it consisted of way too many if-statements. In JavaScript, I could've improved it, but in ABAP I'm a bit lost because I'm missing my arrays. I found out that internal tables are used instead, but I still can't figure it out.

The code is placed in a column of a query manager made by EPI-USE. It's just a way to adjust some results of the query and I noticed I get an error if I try to create a report ("already in a program") and if I create a class or a method ("close try-catch-block before declaring new Class").

The problem is extremely simple:

There's a person that has many properties, the values are numbers. These are the properties:

PA0013-RVNUM

PA0013_01-PERNR
PA0013_02-PERNR
PA0013_03-PERNR
PA0013_04-PERNR
PA0013_05-PERNR
PA0013_06-PERNR

PA0000_01-STAT2
PA0000_02-STAT2
PA0000_03-STAT2
PA0000_04-STAT2
PA0000_05-STAT2
PA0000_06-STAT2

I want to Loop through the PA0013-block and follow These rules:

Conditions:

If PA0013-RVNUM is empty all other properties have to be set to empty.

If a PA0013-value is empty all following PA0013-values have to be set to empty (not the previous ones).

If a PA0013-value is empty the corresponding PA0000-value has to be set to empty.

After the first Loop:

If any of the PA0000-values has the value 3 execute the command REJECT in order to kick the line out of the results.

My JS Code for this would look like that:

var pa0013Array = [
    PA0013_01-NUM
    PA0013_02-NUM
    PA0013_03-NUM
    PA0013_04-NUM
    PA0013_05-NUM
    PA0013_06-NUM];

var pa0000Array = [
    PA0000_01-NUM
    PA0000_02-NUM
    PA0000_03-NUM
    PA0000_04-NUM
    PA0000_05-NUM
    PA0000_06-NUM];

var emptyRest = (PA0005-NUM) ? false : true;

for (var i = 0; i < pa0013Array.length; i++) {

    if (pa0013Array[i] == "") {
        emptyRest = true;
    }

    if (emptyRest) {
        pa0013Array[i] = "";
        pa0000Array[i] = "";
    }
}

if (pa0000Array.indexOf(3) != -1) {
    reject();
}

Can someone help me by "translating" my js code into ABAP?

My colleague just did something like this for all of the conditions:

IF PA0013-RVNUM is INITIAL.
  PA0013_01-PERNR = ''.
  PA0013_02-PERNR = ''.
  PA0013_03-PERNR = ''.
  PA0013_04-PERNR = ''.
  PA0013_05-PERNR = ''.
  PA0013_06-PERNR = ''.
ENDIF.

IF PA0013_01-PERNR = ''.
  PA0013_02-PERNR = ''.
  PA0013_03-PERNR = ''.
  PA0013_04-PERNR = ''.
  PA0013_05-PERNR = ''.
  PA0013_06-PERNR = ''.
ENDIF.

...

IF PA0013_01-PERNR = ''.
  PA0000_01-STAT2 = ''.
ENDIF.

...

IF PA0000_01-STAT2 = 03.
  REJECT.
ENDIF.

He told me he set the PERNRs empty in order for the query not to fill them with wrong PERNRs.

2

There are 2 answers

7
Jagger On BEST ANSWER

Here is how this program could look like. No guarantee at all that it works and does what your JavaScript does.

REPORT ZZZ.

CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS:
      main,
      reject.
  PRIVATE SECTION.
    TYPES:
      BEGIN OF t_num,
        num TYPE string,
      END OF t_num.
    CLASS-DATA:
      pa0013_01 TYPE t_num,
      pa0013_02 TYPE t_num,
      pa0013_03 TYPE t_num,
      pa0013_04 TYPE t_num,
      pa0013_05 TYPE t_num,
      pa0013_06 TYPE t_num,
      pa0000_01 TYPE t_num,
      pa0000_02 TYPE t_num,
      pa0000_03 TYPE t_num,
      pa0000_04 TYPE t_num,
      pa0000_05 TYPE t_num,
      pa0000_06 TYPE t_num,
      pa0005 TYPE t_num.
ENDCLASS.

CLASS lcl_main IMPLEMENTATION.
  METHOD main.
    DATA(lt_pa0013) = VALUE string_table(
      ( pa0013_01-num ) ( pa0013_02-num ) ( pa0013_03-num )
      ( pa0013_04-num ) ( pa0013_05-num ) ( pa0013_06-num )
    ).
    DATA(lt_pa0000) = VALUE string_table(
      ( pa0000_01-num ) ( pa0000_02-num ) ( pa0000_03-num )
      ( pa0000_04-num ) ( pa0000_05-num ) ( pa0000_06-num )
    ).
    DATA: lt_pa0000_hash TYPE SORTED TABLE OF string WITH NON-UNIQUE KEY TABLE_LINE.
    DATA(l_flg_empty_rest) = COND #( WHEN pa0005-num <> 0 THEN abap_false ELSE abap_true ).

    LOOP AT lt_pa0013 ASSIGNING FIELD-SYMBOL(<fs_pa0013>).
      IF <fs_pa0013> IS INITIAL.
        l_flg_empty_rest = abap_true.
      ENDIF.
      IF l_flg_empty_rest = abap_true.
        CLEAR <fs_pa0013>.
        lt_pa0000[ sy-tabix ] = space.
      ENDIF.
    ENDLOOP.

    lt_pa0000_hash = lt_pa0000.

    IF lt_pa0000_hash[ `3` ] IS INITIAL.
      reject( ).
    ENDIF.
  ENDMETHOD.

  METHOD reject.
    ASSERT 0 = 0.
  ENDMETHOD.
ENDCLASS.
0
Suncatcher On

Here is a quick shot for your task.

TYPES: BEGIN OF hr_employee,
        PA0013_rvnum TYPE pa0013-RVNUM,
        PA0013_pernr TYPE pa0013-pernr,
        PA0000_stat1 TYPE pa0000-stat1,
       END OF hr_employee.

DATA: lt_employee TYPE TABLE OF hr_employee.

SELECT a~rvnum a~pernr o~stat1 UP TO 5 ROWS
  INTO TABLE lt_employee
  FROM pa0000 AS o
  JOIN pa0013 AS a
  ON o~pernr = a~pernr.

LOOP AT lt_employee ASSIGNING FIELD-SYMBOL(<fs_emp>).
  IF <fs_emp>-pa0013_pernr IS INITIAL.
    CLEAR <fs_emp>-pa0000_stat1.
    MODIFY lt_employee FROM VALUE hr_employee( PA0013_pernr = space ) TRANSPORTING pa0013_pernr WHERE pa0013_pernr > <fs_emp>-pa0013_pernr.
  ENDIF.
  CHECK <fs_emp>-pa0013_rvnum IS INITIAL.
  CLEAR <fs_emp>.
ENDLOOP.
DELETE lt_employee WHERE pa0013_rvnum = '3'.

It is built on an assumption that infotypes pa0000 and pa0013 use PERNR key that is always ascending in table, so in the above code it is used like a row_number().

The code uses not the horizontal structure like yours (many PERNRs in a row), but a vertical one (one PERNR per line), and lines are treated like attribute tuples (pernr + stat) and the whole dataset represents an employee.

RVNUM can be assigned the same value for all tuples (like in your sample) or different one (like in mine), this code should be valid for both cases.

P.S. Reject() function is not included in the standard JS library, so using it in the productive development you are making your code less transportable sticking only to this custom library, and of course you will receive less answers giving reject() as an example.