Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

What does this runtime error mean?

Former Member
0 Likes
2,327

Hi all, i was asked to complete another ABAPer's unfinished program. When i did a syntax check and activated it, there was no problem. However, when i ran it, i got a runtime error, called ITAB_DUPLICATE_KEY. The code is as follows:


*&---------------------------------------------------------------------*
*&    FORM SEL_REC                                                     *
*&---------------------------------------------------------------------*
FORM SEL_REC.

  SELECT A~MATNR A~MATKL B~MAKTX *error was marked at this line
    INTO TABLE MATPO
    FROM MARA AS A
      INNER JOIN MAKT AS B
        ON A~MATNR = B~MATNR AND
           B~SPRAS = 'EN'
      INNER JOIN MARD AS C
        ON A~MATNR = C~MATNR
    WHERE A~MATNR IN I_MATNR AND
          A~MATKL IN I_MATKL AND
          A~EXTWG IN I_EXTWG AND
          C~WERKS = I_WERKS.

 LOOP AT MATPO.

   SELECT single MAX( A~EBELN ) MAX( A~EBELP ) B~BEDAT B~LIFNR A~MENGE
A~NETPR
   INTO (MATPO-EBELN, MATPO-EBELP, MATPO-BEDAT, MATPO-LIFNR,
   MATPO-MENGE, MATPO-NETPR)
   FROM EKPO AS A
     INNER JOIN EKKO AS B
       ON B~EBELN = A~EBELN
   WHERE A~BSTYP = 'F' AND
         A~MATNR = MATPO-MATNR AND
         A~WERKS = I_WERKS AND
         B~BUKRS = I_BUKRS AND
         A~LOEKZ = ' '
   GROUP BY B~BEDAT B~LIFNR A~MENGE A~NETPR .

   MOVE MATPO-MATNR TO TXT_KEY.

   PERFORM READ_TXT USING 'BEST' TXT_KEY 'MATERIAL'.

   CONCATENATE MATPO-EBELN MATPO-EBELP INTO TXT_KEY.

   PERFORM READ_TXT USING 'F01' TXT_KEY 'EKPO'.

   MODIFY MATPO
     TRANSPORTING EBELN EBELP BEDAT LIFNR MENGE NETPR
     WHERE MATNR = MATPO-MATNR.

 ENDLOOP.

ENDFORM.

Can anyone tell me what is the cause behind the error?

28 REPLIES 28
Read only

Former Member
0 Likes
2,266

How did you define your itab MATPO? You must have defined it with unique key, where as your select can potentially pick up multiple duplicate records because you are going to MARD without full key.

Read only

0 Likes
2,266

Well, this was how it was originally defined, i'm still looking through the original coding...here goes:


TYPES: BEGIN OF TYP_MATPO,
         MATNR LIKE MARA-MATNR,  "Material Number
         MATKL LIKE MARA-MATKL,  "Material Group
         MAKTX LIKE MAKT-MAKTX,  "Material Description
         MENGE LIKE EKPO-MENGE,  "Purchase order quantity
         NETPR LIKE EKPO-NETPR,  "Net price in purchasing document
         BEDAT LIKE EKKO-BEDAT,  "Purchasing Document Date
         LIFNR LIKE EKKO-LIFNR,  "Account Number of the Vendor
         EBELN LIKE EKKO-EBELN,  "Purchasing Document Number
         EBELP LIKE EKPO-EBELP,  "Item Number of Purchasing Document
       END OF TYP_MATPO.

Read only

0 Likes
2,266

I think you'd be better off eliminating the WHERE MATNR = MATPO-MATNR because you are already looping at the matpo table and you will update the same materials multiple times needlessly. Instead, since you are already looping at the table matpo just move sy-tabix into a variable V_VARIABLE that is defined LIKE SY-TABIX. Do this immediately after the loop at so you get the right sy-tabix value as it will change with other table reads. Then when you do your modify statement replace the WHERE MATNR = MATPO-MATNR with INDEX V_VARIABLE. That should work.

Read only

0 Likes
2,266

Bernard,

What you have given is only the TYPE declaration not the internal table. There should be a DATA statement where the internal table will be defined.

I am sure it will be defined with a unique key.

Look for the MATPO internal table.

Regards,

Ravi

Read only

0 Likes
2,266

This is defining your internal table type, but somewhere you must have defined MATPO itself. I want to look at that one.

Srinivas

Read only

govind_seenivasan
Participant
0 Likes
2,266

Hi,

It pasted astructure. Copy and paste the declaration of 'MATPO'. ( It will like : MATPO ..TYP_MATPO ...WITH HEADER LINE )

Thanks

Read only

0 Likes
2,266

Oh, so that what it does, i was looking at it and i didn't know what it meant 😛

Newbie here, many apologies


DATA: MATPO TYPE HASHED TABLE OF TYP_MATPO
        WITH UNIQUE KEY MATNR
        WITH HEADER LINE.

Could anyone explain the use of TYPES, why can't i we use TABLES straight away?

Read only

0 Likes
2,266
DATA: MATPO TYPE HASHED TABLE OF TYP_MATPO
       <b> WITH UNIQUE KEY MATNR</b>
        WITH HEADER LINE.

Yes the highlighted one is what is causing it.

Types are more needed in ABAP objects context. TABLES statement is used only in conjunction with <b>database structures and tables</b><i> not internal tables</i>.

Srinivas

Read only

0 Likes
2,266

So am i suppose to remove it?

Read only

0 Likes
2,266

Bernard,

If you are expecting to process the duplicate entries as well, yes you need to remove the same.

However, I am sure there must be a reason why it's been declared that way. Probably there is something wrong with the data selection because of which it is giving duplicate entries.

Quick solution is to remove it and check the output.

Regards,

Ravi

Read only

0 Likes
2,266

No don't remove it if it is there and you are adding your code on top of it. Remove the MARD select out of your current select and push it into the loop. Since, in your code, you are not looking to do anything with MARD, I suggest you take it out completely. I think what you wanted to do is to see if the material is in a certain plant or not. If that is the case, replace MARD with MARC and it should work.

Read only

0 Likes
2,266

Hi again, i did as u suggested...i removed it and ran the program. It took a very long while and i got a TIME_OUT runtime error...it also marked a particular line, as follows:


*&---------------------------------------------------------------------*
*&    FORM READ_TXT                                                    *
*&---------------------------------------------------------------------*
FORM READ_TXT USING ID XNAME OBJ.

DATA: CTR TYPE I,
      PO_CTR TYPE I.

CLEAR: TXT.  "this line was marked

  SELECT SINGLE * FROM STXH CLIENT SPECIFIED
  INTO WA_STXH
  WHERE MANDT = SY-MANDT AND
        TDOBJECT = OBJ AND
        TDNAME = XNAME AND
        TDID = ID AND
        TDSPRAS  = SY-LANGU.

  IF SY-SUBRC = 0.
    REFRESH txt.
    CTR = 1.
    CALL FUNCTION 'READ_TEXT'
         EXPORTING
              CLIENT   = SY-MANDT
              ID       = ID
              NAME     = XNAME
              OBJECT   = OBJ
              LANGUAGE = SY-LANGU
         TABLES
              LINES    = TXT.

    LOOP AT TXT.
      IF ID = 'BEST'.
        MOVE XNAME TO MATTXT-MATNR.
        MOVE CTR TO MATTXT-CTRT.
        MOVE TXT-TDLINE TO MATTXT-MAT_TXT.
        APPEND MATTXT.
      ELSEIF ID = 'F01'.
        READ TABLE MATTXT WITH KEY MATNR = MATPO-MATNR CTRT = CTR.
        IF SY-SUBRC = 0.
          MOVE TXT-TDLINE TO MATTXT-PO_TXT.
          MODIFY MATTXT TRANSPORTING PO_TXT
          WHERE MATNR = MATPO-MATNR.
        ELSE.
          MOVE MATPO-MATNR TO MATTXT-MATNR.
          MOVE CTR TO MATTXT-CTRT.
          MOVE TXT-TDLINE TO MATTXT-PO_TXT.
          APPEND MATTXT.
        ENDIF.
      ENDIF.
      CTR = CTR + 1.
    ENDLOOP.
  ENDIF.

  SELECT DISTINCT LIFNR NAME1
  FROM LFA1
  INTO TABLE I_LFA1
  FOR ALL ENTRIES IN MATPO
  WHERE SPRAS = 'EN' AND
        LIFNR = MATPO-LIFNR.

ENDFORM.

Read only

0 Likes
2,266

Srinivas, i did as you suggested but i'm still using MARD instead of MARC. When i tried running it, it took too long a time, abt 10 minutes has passed, so i had to stop the transaction. Do you want to have a look at the original coding given to me? I still haven't touch it yet by adding any of my own codes...i'm still trying to understand the flow

Read only

0 Likes
2,266

The code you published tells me that you are selecting records from MARA, MAKT and MARD. While every material selected from MARA has only one corresponding description for a give language in MAKT, the same is not true with MARD. A material can be extended to any number of locations within a particular plant. Since your internal table does not allow multiple entries for the same material, you cannot use it. Using MARC instead of MARD will ensure that for each material you selected from MARA, there is only one or none for the plant I_WERKS in MARC.

It may be timing out for some other reason. What were you asked to change in this program? Is it related to performance or the runtime error you originally got or entirely different reason?

Srinivas

Read only

0 Likes
2,266

Your timeout error may actually be coming after the selection from MARA, MAKT and MARD. When you are looping at MATPO, you are doing a select from EKPO and EKKO and doing group operation MAX on the columns directly. This will consume lot of time. Also, your join uses lot of fields in the WHERE clause that may be resulting in a sequential search instead of indexed search. Remove your B~BUKRS condition from the where clause and put it after the select statement as follows.

CHECK EKKO-BUKRS = I_BUKRS. If this does not improve the performance significantly, remove the BSTYP from the where clause and do a similar check as BUKRS.

Srinivas

Read only

0 Likes
2,266

Sorry for the late reply, i had to participate in a key user training session so i couldn't get back on this until now.

Here's what was originally written in the program and i'm suppose to fill up the blanks:


REPORT  ZLPUPO03 NO STANDARD PAGE HEADING LINE-SIZE 275 LINE-COUNT 65
MESSAGE-ID Z00.

TABLES: EKKO,  "Purchasing Document Header
        EKPO,  "Purchasing Document Item
        MAKT,  "Material Descriptions
        MARA,  "General Material Data
        MARD.  "Storage Location Data for Material
*        LFA1,  "Vendor Master (General Section)
*        STXH.  "STXD SAPscript text file header

TYPES: BEGIN OF TYP_MATPO,
         MATNR LIKE MARA-MATNR,  "Material Number
         MATKL LIKE MARA-MATKL,  "Material Group
         MAKTX LIKE MAKT-MAKTX,  "Material Description
         MENGE LIKE EKPO-MENGE,  "Purchase order quantity
         NETPR LIKE EKPO-NETPR,  "Net price in purchasing document
         BEDAT LIKE EKKO-BEDAT,  "Purchasing Document Date
         LIFNR LIKE EKKO-LIFNR,  "Account Number of the Vendor
         EBELN LIKE EKKO-EBELN,  "Purchasing Document Number
         EBELP LIKE EKPO-EBELP,  "Item Number of Purchasing Document
       END OF TYP_MATPO.

DATA: MATPO TYPE HASHED TABLE OF TYP_MATPO
        WITH UNIQUE KEY MATNR
        WITH HEADER LINE.

TYPES: BEGIN OF TYP_POIN,
         EBELN LIKE EKKO-EBELN,  "Purchasing Document Number
         EBELP LIKE EKPO-EBELP,  "Item Number of Purchasing Document
         BEDAT LIKE EKKO-BEDAT,  "Purchasing Document Date
         LIFNR LIKE EKKO-LIFNR,  "Account Number of the Vendor
         MENGE LIKE EKPO-MENGE,  "Purchase order quantity
         PEINH LIKE EKPO-PEINH,  "Price unit
       END OF TYP_POIN.

DATA: POIN TYPE HASHED TABLE OF TYP_POIN
        WITH UNIQUE KEY EBELN EBELP
        WITH HEADER LINE.

TYPES: BEGIN OF TYP_MATTXT,
         MATNR LIKE MARA-MATNR,  "Material Number
         CTRT TYPE I,
         MAT_TXT(80) TYPE C,
         PO_TXT(80) TYPE C,
       END OF TYP_MATTXT.

DATA: MATTXT TYPE TYP_MATTXT OCCURS 0 WITH HEADER LINE.

TYPES: BEGIN OF TYP_LFA1,
         LIFNR LIKE LFA1-LIFNR,  "Account Number of Vendor or Creditor
         NAME1 LIKE LFA1-NAME1,  "Name 1
       END OF TYP_LFA1.

DATA: I_LFA1 TYPE HASHED TABLE OF TYP_LFA1
       WITH UNIQUE KEY LIFNR
       WITH HEADER LINE.

DATA: WA_STXH TYPE STXH,
      TXT LIKE TLINE OCCURS 0 WITH HEADER LINE,
      TXT_KEY LIKE STXH-TDNAME,  "Name
      L_PAGE_COUNT(5) TYPE C.

*&---------------------------------------------------------------------*
*&    SELECTION-SCREEN                                                 *
*&---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK 1 WITH FRAME TITLE TEXT-001.
PARAMETERS: I_BUKRS LIKE EKKO-BUKRS DEFAULT 'GSPC' OBLIGATORY,
            I_WERKS LIKE MARD-WERKS DEFAULT '6000' OBLIGATORY.
SELECT-OPTIONS: I_MATNR FOR MARA-MATNR,
                I_MTART FOR MARA-MTART,
                I_MATKL FOR MARA-MATKL,
                I_EXTWG FOR MARA-EXTWG.
SELECTION-SCREEN END OF BLOCK 1.

*&---------------------------------------------------------------------*
*&    START-OF-SELECTION                                               *
*&---------------------------------------------------------------------*
START-OF-SELECTION.

  PERFORM INITIALIZE.
  PERFORM SEL_REC.
  PERFORM WRT_REP.
  PERFORM PAGE_COUNT.

*&---------------------------------------------------------------------*
*&    FORM INITIALIZE                                                  *
*&---------------------------------------------------------------------*
FORM INITIALIZE.

  CLEAR: POIN, MATPO.
  REFRESH: POIN, MATPO.
  
ENDFORM.

*&---------------------------------------------------------------------*
*&    FORM SEL_REC                                                     *
*&---------------------------------------------------------------------*
FORM SEL_REC.

  SELECT A~MATNR A~MATKL B~MAKTX
    INTO TABLE MATPO
    FROM MARA AS A
      INNER JOIN MAKT AS B
        ON A~MATNR = B~MATNR AND
           B~SPRAS = 'EN'
      INNER JOIN MARD AS C
        ON A~MATNR = C~MATNR
    WHERE A~MATNR IN I_MATNR AND
          A~MATKL IN I_MATKL AND
          A~EXTWG IN I_EXTWG AND
          C~WERKS = I_WERKS.

 LOOP AT MATPO.

   SELECT single MAX( A~EBELN ) MAX( A~EBELP ) B~BEDAT B~LIFNR A~MENGE
A~NETPR
   INTO (MATPO-EBELN, MATPO-EBELP, MATPO-BEDAT, MATPO-LIFNR,
   MATPO-MENGE, MATPO-NETPR)
   FROM EKPO AS A
     INNER JOIN EKKO AS B
       ON B~EBELN = A~EBELN
     INNER JOIN MARD AS C
       ON A~MATNR = C~MATNR AND
          A~WERKS = C~WERKS
   WHERE A~BSTYP = 'F' AND
         A~MATNR = MATPO-MATNR AND
         A~WERKS = I_WERKS AND
         B~BUKRS = I_BUKRS AND
         A~LOEKZ = ' '
   GROUP BY B~BEDAT B~LIFNR A~MENGE A~NETPR .

   MOVE MATPO-MATNR TO TXT_KEY.

   PERFORM READ_TXT USING 'BEST' TXT_KEY 'MATERIAL'.

   CONCATENATE MATPO-EBELN MATPO-EBELP INTO TXT_KEY.

   PERFORM READ_TXT USING 'F01' TXT_KEY 'EKPO'.

   MODIFY MATPO
     TRANSPORTING EBELN EBELP BEDAT LIFNR MENGE NETPR
     WHERE MATNR = MATPO-MATNR.

 ENDLOOP.

ENDFORM.

*&---------------------------------------------------------------------*
*&    FORM READ_TXT                                                    *
*&---------------------------------------------------------------------*
FORM READ_TXT USING ID XNAME OBJ.

DATA: CTR TYPE I,
      PO_CTR TYPE I.

CLEAR: TXT.

  SELECT SINGLE * FROM STXH CLIENT SPECIFIED
  INTO WA_STXH
  WHERE MANDT = SY-MANDT AND
        TDOBJECT = OBJ AND
        TDNAME = XNAME AND
        TDID = ID AND
        TDSPRAS  = SY-LANGU.

  IF SY-SUBRC = 0.
    REFRESH txt.
    CTR = 1.
    CALL FUNCTION 'READ_TEXT'
         EXPORTING
              CLIENT   = SY-MANDT
              ID       = ID
              NAME     = XNAME
              OBJECT   = OBJ
              LANGUAGE = SY-LANGU
         TABLES
              LINES    = TXT.

    LOOP AT TXT.
      IF ID = 'BEST'.
        MOVE XNAME TO MATTXT-MATNR.
        MOVE CTR TO MATTXT-CTRT.
        MOVE TXT-TDLINE TO MATTXT-MAT_TXT.
        APPEND MATTXT.
      ELSEIF ID = 'F01'.
        READ TABLE MATTXT WITH KEY MATNR = MATPO-MATNR CTRT = CTR.
        IF SY-SUBRC = 0.
          MOVE TXT-TDLINE TO MATTXT-PO_TXT.
          MODIFY MATTXT TRANSPORTING PO_TXT
          WHERE MATNR = MATPO-MATNR.
        ELSE.
          MOVE MATPO-MATNR TO MATTXT-MATNR.
          MOVE CTR TO MATTXT-CTRT.
          MOVE TXT-TDLINE TO MATTXT-PO_TXT.
          APPEND MATTXT.
        ENDIF.
      ENDIF.
      CTR = CTR + 1.
    ENDLOOP.
  ENDIF.

  SELECT DISTINCT LIFNR NAME1
  FROM LFA1
  INTO TABLE I_LFA1
  FOR ALL ENTRIES IN MATPO
  WHERE SPRAS = 'EN' AND
        LIFNR = MATPO-LIFNR.

ENDFORM.

*&---------------------------------------------------------------------*
*&    FORM WRT_REP                                                     *
*&---------------------------------------------------------------------*
FORM WRT_REP.

  SORT MATTXT BY MATNR CTRT.
  LOOP AT MATPO.
    WRITE:/2 MATPO-MATNR(10),
          12 MATPO-MATKL,
          21 MATPO-MAKTX(30).
*          51 MATPO-.
    LOOP AT MATTXT
      WHERE MATNR = MATPO-MATNR.
*      IF TYP_MATTXT-CTRT = 1.
        WRITE: 51 MATTXT-MAT_TXT, MATTXT-PO_TXT.
*      ELSE.
*        WRITE:/ 51 MATTXT-MAT_TXT, MATTXT-PO_TXT.
*      ENDIF.
    ENDLOOP.
  ENDLOOP.

ENDFORM.

I'm still trying to understand the flow and its logic. What i don't get is why TYPES was used? Was it really necessary to do it in such a way to begin with? No spec doc was provided for this program, so i'm pretty much given instructions verbally. From what i could understand, i am to enable the program to output the following in the report based on certain selection criteria input by the user:

Material Code (MARA-MATNR)

Material Group (MARA-MATKL)

Material Description (MAKT-MAKTX)

Material PO Text (Can't find it)

Item Text/Specification (Can't find it)

Last Purchase Quantity (EKPO-MENGE)

Last Purchase Price (EKPO-PEINH)

Last Purchase Date (EKKO-BEDAT)

Last Purchase Vendor (LFA1-NAME1)

Srinivas, you mentioned something abt doing away with MARD or replacing it with MARC, but won't touch it yet as i'm still looking into it as to why MARD was used by the pervious ABAPer

Read only

0 Likes
2,266

TYPES are used to replace the older coding style.

Old Code Style.

Data: begin of itab occurs 0,
      fld1 type c,
      fld2 type c,
      end of itab.

New Code Style.


Types: begin of ttab,
       fld1 type c,
       fld2 type c,
       end of ttab.
data: itab type table of ttab.
data: wa type ttab.

This is because with ABAP Objects, the OCCURS 0 is not allowed as are header lines. So you must have a work area.

Regards,

Rich Heilman

Read only

0 Likes
2,266

Heh, thanks Rich, i didn't know that

But i don't quite get last time of your example:


data: wa type ttab.

What is it suppose to represent?

Read only

0 Likes
2,266

I meant the last line

Read only

0 Likes
2,266

That line represents the work area for the internal table. When you define an internal table using the OCCURS 0, the header line is there automatically. It is suggested by SAP that you no longer use this syntax. Rather you use the TYPE TABLE OF syntax and then define a work area for the internal table. If you are outside of the OO scope, then there is nothing stopping you from using the WITH HEADER LINE extension.

Data: itab type table of ttab WITH HEADER LINE.

You need a header line to access the table. So in this case, with a work area you would access the table like this.



Loop at itab INTO WA.

if WA-FLD1 = 'X'.
wa-fld2 = 'X'.
modify itab from wa.
Endif.

ENDLOOP.



If you were using the older syntax, it would be something like this.




Loop at itab.
if itab-FLD1 = 'X'.
itab-fld2 = 'X'.
modify itab.
Endif.
endloop.

Again, the reason for the work area is because OCCURS 0 and WITH HEADER LINE are not supported in ABAP Objects.

Make sense?

Regards,

Rich Heilman

Read only

0 Likes
2,266

Not really, the older syntax makes more sense to me, maybe because i started learning with it 😛

However, since the program was originally written that way, i might as follow that style and pick it up, still learning, right?

But when you say "LOOP AT ITAB INTO WA"...does it mean i would have to define WA? And is WA a standard name? Or i could use some other name to replace it?

Thanks Rich

Read only

0 Likes
2,266

Yes, you need to define WA. The naming convention for internal tables is...

Data: IT_ITAB type table of TTAB.
data: wa_ITAB type ttab.

I don't really like this, so I usually use something like this.

Data: iAfko type table of afko.
data: xafko type afko.

I just like it better.

I would suggest learning the new syntax as it will become importing when learning ABAP objects.

Regards,

Rich Heilman

Read only

0 Likes
2,266

Thanks Rich,

I'll play around with it so i could understand more on it...

Ok, i removed the B~BUKRS = I_BUKRS and BSTYP = 'F' conditions from the WHERE clause and replaced MARD with MARC, it worked...performance was significantly improved, at least i get to display the results but it still took a while...500+ records 😛

Anyone has any ideas on how to improve the performance further?

Read only

0 Likes
2,266

Hi Bernard,

Looks like some of my suggestions worked and I already explained that TYPES are used in more ABAP objects context as implicit work area that is provided using BEGIN OF with OCCURS option of an internal table declaration is not allowed in ABAP objects context.

Concentrate on your second select.

Srinivas

Read only

0 Likes
2,266

Oh, and i also got back to the consultant and mentioned about using MARC instead of MARD, it seems that i need to stick with using MARD. I went through SE11 and did a query and i noticed that the records that are displayed in MARD is more than in MARC...shouldn't it have the same amount records?

Read only

Former Member
0 Likes
2,266

Hi,

i gone through ur code the first mistake u made was u defined matpo as type later u had to define it as a int table from that type but i think u didn't and another problem u r facing is a long response time b'coz of the second loop and ur selection criteria.instead of all these just u declare a internal table by using the fields from all the tables and use a single selection criteria to retrive the data.if this is not clear for u.send the code i'll make the modifications.

Regards,

suresh

Read only

0 Likes
2,266

It's ok...i need to solve it myself...i'm still at the learning process

I won't close the thread yet, i'm still working on it, i'll post question if i have any.

Read only

0 Likes
2,266

Hi again...i have a question to ask...if you look back at the original codes i posted, there is a subroutine called READ_TXT. Within it, there is a call function 'READ TEXT', so i went into SE37 to find out what is it all about. The thing is that i don't get it, i don't see what the original ABAPer intends to do with it. Couldn't the text be output immediately by doing a WRITE statement?