Application Development 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: 

How to use data of 3 internal tables?

0 Kudos

I get the required data in 3 internal tables. How can I get a report which will print :

1. Material Number

2. Material Description

3. Plant

4. Plant Description as output for the given Material Number.

I am a bit confused about retrieving the data from it_too1w when no field matches with MARC and MAKT Internal tables.

Here is the code :

*&---------------------------------------------------------------------*
*& Report Z_ABAP_ASSIGNMENT2_ADDITION_1
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT Z_ABAP_ASSIGNMENT2_ADDITION_1.

TYPES : BEGIN OF ty_marc,
matnr TYPE MATNR,
werks TYPE WERKS_D,
END OF ty_marc.

TYPES : BEGIN OF ty_makt,
matnr TYPE MATNR,
spras TYPE SPRAS,
maktx TYPE MAKTX,
maktg TYPE MAKTG,
END OF ty_makt.

TYPES : BEGIN OF ty_t001w,
werks TYPE WERKS_D,
name1 TYPE NAME1,
END OF ty_t001w.

DATA : it_marc TYPE ty_marc OCCURS 0,
wa_marc TYPE ty_marc,
it_makt TYPE ty_makt OCCURS 0,
wa_makt TYPE ty_makt,
it_t001w TYPE ty_t001w OCCURS 0,
wa_t001w TYPE ty_t001w.


SELECT-OPTIONS s_matnr FOR wa_makt-matnr NO-EXTENSION NO INTERVALS.

SELECT matnr
spras
maktx
maktg
FROM makt
INTO TABLE it_makt
WHERE matnr IN s_matnr.

IF sy-subrc IS INITIAL.
SELECT matnr
werks
FROM marc
INTO TABLE it_marc
FOR ALL ENTRIES IN it_makt
WHERE matnr EQ it_makt-matnr.
ENDIF.

IF sy-subrc IS INITIAL.
SELECT werks
name1
FROM T001W
INTO TABLE it_t001w
FOR ALL ENTRIES IN it_marc
WHERE werks EQ it_marc-werks.
ENDIF.

WRITE : / 'Material Number',
20 'Material Description',
45 'Plant',
55 'Plant Description' LEFT-JUSTIFIED.
SKIP.

*I am unable to understand how to use 3 IT for output.

LOOP AT it_makt INTO wa_makt.
* READ TABLE it_t001w INTO wa_t001w WITH TABLE KEY.
WRITE wa_makt-matnr.
WRITE 20 wa_makt-maktx.
WRITE 45 wa_t001w-werks.
WRITE 55 wa_t001w-name1 LEFT-JUSTIFIED.

ENDLOOP.

1 ACCEPTED SOLUTION

mateuszadamus
Active Contributor

Hi
First, you should add the SPRAS condition to the MAKT SELECT.

Then, when it comes to reading internal tables.

LOOP AT it_makt INTO wa_makt. 
LOOP AT it_marc INTO wa_marc WHERE matnr = wa_makt-matnr. " LOOP because there can be many records per one material READ TABLE it_t001w INTO wa_t001w WITH KEY weeks = wa_marc-werks. " READ TABLE because there will be only one record per plant IF sy-subrc = 0. WRITE: / ... ENDIF. ENDLOOP.
ENDLOOP.

You should create the IT_MARC and IT_T001W internal tables as sorted with key on MATNR and WERKS for better performance.
Regards,
Mateusz

17 REPLIES 17

venkateswaran_k
Active Contributor

Hi

You can achieve it in single Query itself.

SELECT matnr, maktx, werks, name1 FROM
MARC as a
INNER JOIN MAKT as b ON a~MATNR eq b~MATNR
INNER JOIN T001W as c ON a~WERKS eq c~WERKS
INTO CORRESPONDING FIELDS OF TABLE your_output_internaltable
WHERE a~matnr in s_matnr AND b~SPARS EQ SY-LANGU 
 

0 Kudos

I would recommend the explicit addressing of tables where the columns come from:

SELECT a~matnr, b~maktx, a~werks, c~name1

LEFT OUTER JOIN might be preferred over INNER JOIN for MAKT, in case the material text isn't defined for some materials in the current language.

I'd recommend using the full table name - it's clearer:

SELECT marc~matnr, makt~maktx, marc~werks, t001w~name1 FROM
MARC as marc
INNER JOIN MAKT as makt ON marc~MATNR eq makt~MATNR
INNER JOIN T001W as t001w ON marc~WERKS eq t001w~WERKS
INTO CORRESPONDING FIELDS OF TABLE your_output_internaltable
WHERE marc~matnr in s_matnr AND makt~SPRAS EQ SY-LANGU 

(Looking at it, I'm not sure you need the as table ... I don't have a sap system at the moment to check).

0 Kudos

It's not needed.

Regards,
Mateusz

0 Kudos
Matthew Billingham As Mateusz said, "table AS table" is not needed if the alias is the same name as the table.

mateuszadamus
Active Contributor

Hi
First, you should add the SPRAS condition to the MAKT SELECT.

Then, when it comes to reading internal tables.

LOOP AT it_makt INTO wa_makt. 
LOOP AT it_marc INTO wa_marc WHERE matnr = wa_makt-matnr. " LOOP because there can be many records per one material READ TABLE it_t001w INTO wa_t001w WITH KEY weeks = wa_marc-werks. " READ TABLE because there will be only one record per plant IF sy-subrc = 0. WRITE: / ... ENDIF. ENDLOOP.
ENDLOOP.

You should create the IT_MARC and IT_T001W internal tables as sorted with key on MATNR and WERKS for better performance.
Regards,
Mateusz

0 Kudos

With ABAP >= 7.40, prefer table expressions over READ TABLE.

ASSIGN it_t001w[ werks = wa_marc-werks ] TO FIELD-SYMBOL(<t001w>).
IF sy-subrc = 0.
  ...
ENDIF.

or

TRY.
    DATA(wa_t001w) = it_t001w[ werks = wa_marc-werks ].
  CATCH cx_sy_itab_line_not_found.
    ...
ENDIF.
...

0 Kudos

Hi Sandra,

Apart from less code, which doesn't always go together with a better readability, table expressions do not give any performance gain compared to READ TABLE. I would say it's up to a developer to use one or the other.

Regards,

Mateusz

0 Kudos

I have tried to do what you suggest but still unable to achieve results. Kindly see my code if there is any problem. Performance suggestion I will implement later. First let it run correctly.

Also, I have seen somewhere that it is not recommended to use LOOP within LOOP in ABAP. One should use LOOP and then READ in that. How can we achieve he result with a single LOOP.

TYPES : BEGIN OF ty_marc,
        matnr TYPE MATNR,
        werks TYPE WERKS_D,
  END OF ty_marc.

TYPES : BEGIN OF ty_makt,
        matnr TYPE MATNR,
        spras TYPE SPRAS,
        maktx TYPE MAKTX,
        maktg TYPE MAKTG,
  END OF ty_makt.

TYPES : BEGIN OF ty_t001w,
        werks TYPE WERKS_D,
        name1 TYPE NAME1,
 END OF ty_t001w.

 DATA : it_marc TYPE ty_marc OCCURS 0,
        wa_marc TYPE ty_marc,
        it_makt TYPE ty_makt OCCURS 0,
        wa_makt TYPE ty_makt,
        it_t001w TYPE ty_t001w OCCURS 0,
        wa_t001w TYPE ty_t001w.


SELECT-OPTIONS s_matnr FOR wa_makt-matnr NO-EXTENSION NO INTERVALS.

SELECT matnr
       spras
       maktx
       maktg
           FROM makt
           INTO TABLE it_makt
           WHERE matnr IN s_matnr AND spras = 'EN'.

 IF sy-subrc IS INITIAL.
   SELECT matnr
          werks
           FROM marc
           INTO TABLE it_marc
           FOR ALL ENTRIES IN it_makt
           WHERE matnr EQ it_makt-matnr.
ENDIF.

IF sy-subrc IS INITIAL.
 SELECT werks
        name1
           FROM T001W
           INTO TABLE it_t001w
           FOR ALL ENTRIES IN it_marc
           WHERE werks EQ it_marc-werks.
ENDIF.

WRITE : / 'Material Number',
        20 'Material Description',
        45 'Plant',
        55 'Plant Description' LEFT-JUSTIFIED.
SKIP.

     LOOP AT it_makt INTO wa_makt.
       LOOP AT it_marc INTO wa_marc WHERE matnr EQ wa_makt-matnr.
         READ TABLE it_t001w INTO wa_t001w WITH KEY werks = wa_marc-werks.
         WRITE wa_makt-matnr.
         WRITE 20 wa_makt-maktx.
         WRITE 45 wa_marc-werks.
         WRITE 55 wa_t001w-name1 LEFT-JUSTIFIED.
       ENDLOOP.
     ENDLOOP.

0 Kudos

Hi

What do you mean there are no results? Do you have an error? Nothing is printed? Did you debug the code to see what is going on? Please provide more information.

"Also, I have seen somewhere that it is not recommended to use LOOP within LOOP in ABAP. One should use LOOP and then READ in that. How can we achieve he result with a single LOOP."

It all depends on the situation. For sure it's not recommended to use neither LOOP nor READ TABLE in another LOOP, if the table used for inner expression is not sorted and you're not reading it with the use of a key.

Example of bad inner read:

DATA:
  lt_vbak TYPE TABLE OF vbak,
  lt_vbap TYPE TABLE OF vbap.

LOOP AT lt_vbak REFERENCE INTO DATA(ld_vbak).
  " because table is not sorted
  " system will go through all the records to find the relevant ones
  LOOP AT lt_vbap REFERENCE INTO DATA(ld_vbap)
    WHERE vbeln = ld_vbak->vbeln.
  ENDLOOP.
ENDLOOP.

Example of proper inner read:

DATA:
  lt_vbak TYPE TABLE OF vbak,
  lt_vbap TYPE SORTED TABLE OF vbap WITH UNIQUE KEY vbeln posnr.

LOOP AT lt_vbak REFERENCE INTO DATA(ld_vbak).
  " table is sorted with key containing the VBELN field
  " system will use that key
  LOOP AT lt_vbap REFERENCE INTO DATA(ld_vbap)
    WHERE vbeln = ld_vbak->vbeln.
  ENDLOOP.
ENDLOOP.

Documentation on the LOOP can be found here. I strongly encourage you to read the documentation. It's not that boring as it may seem 😉 and it really gives valuable information on many aspects of ABAP keywords.

From that documentation:

"When standard tables are accessed without a secondary key being specified, the access is not optimized. This means that all rows of the internal table are tested for the logical expression of the WHERE addition."

Regards,

Mateusz

0 Kudos

I have got the following output when I enter 412 in the Material Number.

I am unable to get why only 1 entry is printing while it has 2.

Also I have created the IT_MARC and IT_T001W internal tables as sorted with key on MATNR and WERKS for better performance. Kindly check if I did it right. Here is the full code :

REPORT Z_ABAP_ASSIGNMENT2_ADDITION_1.

TYPES : BEGIN OF ty_marc,
        matnr TYPE MATNR,
        werks TYPE WERKS_D,
  END OF ty_marc.

TYPES : BEGIN OF ty_makt,
        matnr TYPE MATNR,
        spras TYPE SPRAS,
        maktx TYPE MAKTX,
        maktg TYPE MAKTG,
  END OF ty_makt.

TYPES : BEGIN OF ty_t001w,
        werks TYPE WERKS_D,
        name1 TYPE NAME1,
 END OF ty_t001w.

 DATA : it_marc TYPE SORTED TABLE OF ty_marc WITH NON-UNIQUE KEY matnr,
        wa_marc TYPE ty_marc,
        it_makt TYPE ty_makt OCCURS 0,
        wa_makt TYPE ty_makt,
        it_t001w TYPE SORTED TABLE OF ty_t001w WITH NON-UNIQUE KEY werks,
        wa_t001w TYPE ty_t001w.

SELECT-OPTIONS s_matnr FOR wa_makt-matnr NO-EXTENSION NO INTERVALS.

SELECT matnr
       spras
       maktx
       maktg
           FROM makt
           INTO TABLE it_makt
           WHERE matnr IN s_matnr AND spras = 'EN'.

 IF sy-subrc IS INITIAL.
   SELECT matnr
          werks
           FROM marc
           INTO TABLE it_marc
           FOR ALL ENTRIES IN it_makt
           WHERE matnr EQ it_makt-matnr.
ENDIF.

IF sy-subrc IS INITIAL.
 SELECT werks
        name1
           FROM T001W
           INTO TABLE it_t001w
           FOR ALL ENTRIES IN it_marc
           WHERE werks EQ it_marc-werks.
ENDIF.

WRITE : / 'Material Number',
        20 'Material Description',
        45 'Plant',
        55 'Plant Description' LEFT-JUSTIFIED.
SKIP.

     LOOP AT it_makt INTO wa_makt.
       LOOP AT it_marc INTO wa_marc WHERE matnr EQ wa_makt-matnr.
         READ TABLE it_t001w INTO wa_t001w WITH TABLE KEY werks = wa_marc-werks.
         WRITE wa_makt-matnr.
         WRITE 20 wa_makt-maktx.
         WRITE 45 wa_marc-werks.
         WRITE 55 wa_t001w-name1 LEFT-JUSTIFIED.
       ENDLOOP.
     ENDLOOP.

0 Kudos

Look at 412 on the right of your screenshot... Understand? You should write the next material/plant to a new line.

0 Kudos

I added the SKIP statement as shown below.

LOOP AT it_makt INTO wa_makt.
       LOOP AT it_marc INTO wa_marc WHERE matnr EQ wa_makt-matnr.
        SKIP.
         READ TABLE it_t001w INTO wa_t001w WITH TABLE KEY werks = wa_marc-werks.
         WRITE wa_makt-matnr.
         WRITE 20 wa_makt-maktx.
         WRITE 45 wa_marc-werks.
         WRITE 55 wa_t001w-name1 LEFT-JUSTIFIED.
       ENDLOOP.
     ENDLOOP.

It worked and I got the following output. But what should I do so that between each row of 412 there is no space?

Also strangely if I comment out the SKIP statement from the code above, it gives the following output :

I am unable to find why this is happening? I got output without any line breaks when I used loops in some other programs.

Hi

Use "WRITE /" instead of "SKIP".

Regards,

Mateusz

Sandra_Rossi
Active Contributor

Please use the CODE button to format your code so that it's shown in a more user-friendly format (colorized).

Sandra_Rossi
Active Contributor

You are using very old/obsolete ABAP. OCCURS is obsolete since 6.10. There are table expressions since 7.40 (instead of READ TABLE). You should prefer joins over FOR ALL ENTRIES.

(+ prefer using ABAP Objects)

former_member1716
Active Contributor

harbindersingh,

There are few guidelines expected before posting a query to the forum,

1) Use the code option to paste any code.

2) Before posting ensure you have done enough research for the requirement. Your requirement here is basic one, if you had spent some time in seeing few sample codes you would have resolved it yourself.

3) Always try to understand the coding features first, like Sandra Rossi Suggested refrain from using obselete codes.

Regards!