1

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

Cold_Class
  • 3,214
  • 4
  • 39
  • 82
  • 1
    Can you include your colleague's code in the question so we can evaluate it? – Nelson Miranda Feb 29 '16 at 15:38
  • Why do you write empty strings to your arrays where you actually expect numbers? – Jagger Feb 29 '16 at 15:52
  • because I actually don't know which type they are, I just now that all I see is numbers and that "PA0000_01-NUM = '' " from my colleague's code worked somehow I guess...he just wanted to overwrite the value no matter with what I think – Cold_Class Feb 29 '16 at 20:02
  • my colleagues code is too long and not relevant to my core question (in the title) All he did was making an if statement for every single field and that is the reason why he didn't need to create an internal table and his code is too long – Cold_Class Feb 29 '16 at 20:05

2 Answers2

2

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.
Jagger
  • 10,350
  • 9
  • 51
  • 93
  • 1
    Nice, that You already use the new syntax, but You fall back to old one by this: READ TABLE lt_pa0000_hash WITH TABLE KEY table_line = `3` TRANSPORTING NO FIELDS. IF sy-subrc <> 0. reject( ). – icbytes Feb 29 '16 at 16:41
  • @icbytes I tried to use lt_pa0000_hash[ `'3'` ] but somehow could not get through with it. If you know how to do it, then improvements to the code are welcome! – Jagger Feb 29 '16 at 16:57
  • Line exist prior perhaps? Or try catch around this stuff. – icbytes Feb 29 '16 at 17:06
  • thank you, this looks nice - more lines of code than I was hoping for, but I have to accept the fact that ABAP isn't JS haha I will try this code at work tmrw and tell you how it went :) – Cold_Class Feb 29 '16 at 20:10
  • One tip. Try to define more properly, what You want to achieve. All of Your code looks like self learning. If so, You would already learn from us by telling You some better ways for whatever. Welcome to abap. By the way, are You familiar with android java? – icbytes Feb 29 '16 at 21:20
  • @Cold_Class I have tidied up the code a bit. It is shorter and more readable now. – Jagger Mar 01 '16 at 10:59
  • hmm not quite working - I noticed I can't declare classes and methods in my "Ausdruckseditor" = "Expressioneditor" - icbytes is right, I will edit and define my question more properly. @icbytes No, I just have a bit of regular Java knowledge but I want to create my first android-app one day so I hope to get to know it soon ;) – Cold_Class Mar 01 '16 at 12:04
0

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.

Suncatcher
  • 10,355
  • 10
  • 52
  • 90