Interne Tabelle mit Zeilen füllen

Getting started ... Alles für einen gelungenen Start.
11 Beiträge • Seite 1 von 1
11 Beiträge Seite 1 von 1

Interne Tabelle mit Zeilen füllen

Beitrag von Sonne1234 (ForumUser / 30 / 16 / 1 ) » 18.12.2019 16:30

Hallo zusammen,

ich habe eine interne Tabelle gt_zzzz. In dieser befindet sich das Feld object_ID. Die interne Tabelle ist zu Beginn leer.

Diese möchte ich nun mit Daten aus der Tabelle gt_bkpf anreichern. Und zwar soll nur die Spalte gt_bkpf-rfsch in die Spalte gt_zzzz-object_ID übernommen werden.

Die erste Idee war hierzu die folgende:

Code: Alles auswählen.

Insert LINES OF gt_bkpf from gt_bkpf-rfsch to gt_zzzz-object_id. 
Hier bekomme ich aber mal wieder meine Lieblingsmeldung "GT_BKPF ist eine Tabelle ohne Kopfzeile und besitzt daher keine Komponente mit Namen RFSCH."

Wo ist hier mein Fehler?

Ich kann leider nicht die eine Tabelle einfach in die andere schreiben, da ich nur dieses eine Feld hier benötige und ich sonst an anderer Stelle Probleme bekomme.

Die zweite Überlegung war, dies mit einem SELECT zu lösen. Aber da bleibe ich dann sehr schnell stehen, da ich eigentlich keine WHERE-Bedingung habe. Ich möchte einfach generell alle Einträge übernehmen.

Ich wäre um eure Hilfe sehr dankbar.
Liebe Grüße
Julia



Re: Interne Tabelle mit Zeilen füllen

Beitrag von Aba (ForumUser / 49 / 6 / 1 ) » 19.12.2019 07:04

Hallo Julia,

wie wäre es mit folgendem?

Code: Alles auswählen.

data: ls_zzzz like line of gt_zzzz,
         ls_bkpf like line of gt_bkpf.

loop at gt_bkpf into ls_bkpf.
     ls_zzzz-object_ID = ls_bkpf-rfsch.
     append ls_zzzz to gt_zzzz.
endloop.

Re: Interne Tabelle mit Zeilen füllen

Beitrag von DeathAndPain (Top Expert / 1261 / 138 / 290 ) » 19.12.2019 08:08

Zu aufwendig. Aufbau von internen Tabellen über Workareas stammt aus der Zeit von vor Release 7.40 und sollte heutzutage nur noch in begründeten Ausnahmefällen gemacht werden.

Für Julias Anforderung reicht ein Einzeiler:

Code: Alles auswählen.

gt_zzzz = VALUE #( FOR <zeile> IN gt_bkpf ( object_ID = <zeile>-rfsch ) ).
Fertig. Da brauchste dann auch weiter keine Hilfsfelder zu deklarieren.
Julia hat geschrieben:Die zweite Überlegung war, dies mit einem SELECT zu lösen. Aber da bleibe ich dann sehr schnell stehen, da ich eigentlich keine WHERE-Bedingung habe. Ich möchte einfach generell alle Einträge übernehmen.
SELECT ist ungeeignet, aber nicht aus dem von Dir genannten Grund, sondern weil man damit nur aus Datenbanktabellen lesen kann, und Du willst Deine Daten ja einer internen Tabelle entnehmen. Die WHERE-Bedingung hingegen ist kein Problem; es ist zulässig, bei SELECT die WHERE-Bedingung einfach wegzulassen, wenn man alle Zeilen einer Datenbanktabelle haben möchte.

Folgende Benutzer bedankten sich beim Autor DeathAndPain für den Beitrag:
Sonne1234 (08.01.2020 15:26)


Re: Interne Tabelle mit Zeilen füllen

Beitrag von black_adept (Top Expert / 3334 / 60 / 617 ) » 19.12.2019 08:25

Weitere Alternative:

Code: Alles auswählen.

gt_zzzz = CORRESPONDING #( gt_bkpf MAPPING object_id = rfsch ).

Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag (Insgesamt 2):
DeathAndPain (19.12.2019 08:49) • Sonne1234 (08.01.2020 15:26)

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Interne Tabelle mit Zeilen füllen

Beitrag von Sonne1234 (ForumUser / 30 / 16 / 1 ) » 08.01.2020 15:44

Hallo zusammen,

in diesem Fall habt ihr mir sehr weitergeholfen. Ich habe hierzu aber noch einen ähnlichen Fall.

Nun möchte ich Daten aus einer internen Tabelle in eine andere interne Tabelle schreiben, bei den das Feld fkart immer den Wert X hat.

In der Tablle gt_vbrk sind z. B. folgende Werte

X 900654654 5265465
Y 900646546 6546546
X 900646546 6654544

Die Tabelle gt_sap soll dann die folgenden Werte enthalten:
X 900654654 5265465
X 900646546 6654544

Meine Ideen hierzu waren die folgenden:

Code: Alles auswählen.

Loop at gt_vbrk into wa_vbrk
    where fkart = 'X'.
    move-CORRESPONDING wa_vbrk to gt_sap. 
  endloop.
Da bekomme ich allerdings die Fehlermeldung "Bei MOVE-CORRESPONDING müssen beide Operanden "WA_VBRK" und "GT_SAP" gleichzeitig Strukturen oder interne Tabellen sein."

Meine Datendeklaration sieht wie folgt aus:

Code: Alles auswählen.

types:  BEGIN OF ty_vbrk,
         vbeln TYPE c length 30,
         fkart TYPE vbrk-fkart,
         fkdat TYPE vbrk-fkdat,
         rfbsk type vbrk-rfbsk,
       END OF ty_vbrk. 
data: wa_vbrk  TYPE ty_vbrk,
        gt_vbrk  TYPE STANDARD TABLE OF ty_vbrk,
      gt_sap type STANDARD TABLE OF ty_vbrk.
Ich habe hier auch schon versucht alles mögliche zu ändern. Dann bekomme ich allerdings an anderer Stelle Probleme.

Der zweite Ansatz war dann, sich an dem Beitrag von @DeathAndPain zu orientieren. Allerdings muss ich zugeben, dass ich das mit den ganzen Klammern noch nicht so ganz verstanden habe.

Code: Alles auswählen.

gt_sap = value #( for gt_vbrk_fkart = 'X' in gt_vbrk ). 
Hierbei kann das IN nicht interpretiert werden.

Dann habe ich folgenden Versuch gestartet:

Code: Alles auswählen.

gt_sap = value #( gt_vbrk[ fkart = 'X' ] ).
Da kommt dann die Meldung ""GT_SAP" und der Zeilentyp von "GT_VBRK" sind nicht ineinander konvertierbar."

Ich verzweifle hier noch an den ganzen Meldungen. Das kann ja vermutlich nicht so schwer sein, so etwas zu übertragen. Ich wäre euch sehr dankbar, wenn ihr mir hier nochmal helfen könntet.

Liebe Grüße
Julia

Re: Interne Tabelle mit Zeilen füllen

Beitrag von Mockingbird (ForumUser / 10 / 7 / 0 ) » 08.01.2020 16:02

Ich habe hier die Funktion ALSM_EXCEL_TO_INTERNAL_TABLE benutzt um ein Excel hochzuladen, allerdings sieht die Tabelle danach furchtbar aus. Mit dem Loop habe ich die Tabelle wieder sortiert. Eventuell hilft das weiter, da beide Strukturen nicht ähnlich waren.

Code: Alles auswählen.

  LOOP AT lt_file.
    CASE lt_file-col.
      WHEN '0001'.
        MOVE lt_file-value TO lt_po_update-location.
      WHEN '0002'.
        MOVE lt_file-value TO lt_po_update-matnr.
      WHEN '0003'.
        MOVE lt_file-value TO lt_po_update-kurtxt.
      WHEN '0004'.
        MOVE lt_file-value TO lt_po_update-justit.
      WHEN '0005'.
        MOVE lt_file-value TO lt_po_update-menge.
      WHEN '0006'.
        MOVE lt_file-value TO lt_po_update-category.
      WHEN '0007'.
        MOVE lt_file-value TO lt_po_update-ebeln.
      WHEN '0008'.
        MOVE lt_file-value TO lt_po_update-eindt.
    ENDCASE.
    AT END OF row.
      APPEND lt_po_update.
      CLEAR lt_po_update.
    ENDAT.
  ENDLOOP.
LG
Mockingbird

Re: Interne Tabelle mit Zeilen füllen

Beitrag von Legxis (Specialist / 153 / 80 / 27 ) » 08.01.2020 16:38

Mit 7.4er Syntax kann ich nicht helfen, aber dein Fehler ist, dass du versuchst, deine gefundene table_line direkt in die Endtabelle zu schreiben, statt erst in eine workarea und dann einzufügen.

Code: Alles auswählen.

DATA: ...
      wa_sap   TYPE ty_vbrk,
      ...

LOOP ...
  MOVE-CORRESPONDING wa_vbrk TO wa_sap.
  INSERT wa_sap INTO gt_sap.              " oder APPEND ... TO ...
ENDLOOP.
Dadurch, dass deine Tabellen die gleiche Struktur haben kannst du die Übergangsstruktur sogar weglassen und kannst direkt so machen:

Code: Alles auswählen.

LOOP ...
  INSERT wa_vbrk INTO gt_sap.              " oder APPEND ... TO ...
ENDLOOP.

Folgende Benutzer bedankten sich beim Autor Legxis für den Beitrag:
Sonne1234 (09.01.2020 11:12)

( SAP ECC 6.0, NetWeaver 7.0, ohne unicode, ohne support/enhancement packages )

Re: Interne Tabelle mit Zeilen füllen

Beitrag von DeathAndPain (Top Expert / 1261 / 138 / 290 ) » 09.01.2020 11:49

Also wenn die beiden Tabellen tatsächlich gleich typisiert sind, dann wäre das ein ganz typischer Anwendungsfall für die filter-Funktion.

Code: Alles auswählen.

gt_sap = FILTER #( gt_vbrk WHERE fkart = 'X' ).
Kurz, gut lesbar und am performantesten.

Ich selber benutze die FILTER-Funktion so gut wie nie, weil es mir nicht sympathisch ist, mit zwei gleich typisierten internen Tabellen zu hantieren. Aber hier scheint ja genau das gefragt zu sein.

Spannender wird es, wenn nicht alle Spalten von gt_sap und gt_vbrk gleich sind. Dann wird man wohl um einen LOOP nicht herumkommen (sofern man nicht einen FILTER #() in ein CORRESPONDING #() verschachteln möchte, was theoretisch auch gehen müsste, dann aber nicht mehr so gut lesbar ist).

Folgende Benutzer bedankten sich beim Autor DeathAndPain für den Beitrag:
Sonne1234 (09.01.2020 12:54)


Re: Interne Tabelle mit Zeilen füllen

Beitrag von ewx (Top Expert / 4116 / 182 / 417 ) » 09.01.2020 11:59

Code: Alles auswählen.

TYPES: BEGIN OF type_one,
         field TYPE c LENGTH 4,
         flag  TYPE abap_bool,
       END OF type_one,
       type_one_table TYPE STANDARD TABLE OF type_one WITH DEFAULT KEY,
       BEGIN OF type_two,
         field TYPE c LENGTH 4,
         dummy TYPE c LENGTH 2,
       END OF type_two,
       type_two_table TYPE STANDARD TABLE OF type_two WITH DEFAULT KEY.

DATA(one) = VALUE type_one_table(
             ( field = 'aa' flag = abap_false )
             ( field = 'bb' flag = abap_true )
             ( field = 'cc' flag = abap_true )
             ( field = 'dd' flag = abap_false ) ).

DATA(two) = VALUE type_two_table( FOR line IN one WHERE ( flag = abap_true ) ( field = line-field ) ).

cl_demo_output=>display_data( two ).

Re: Interne Tabelle mit Zeilen füllen

Beitrag von DeathAndPain (Top Expert / 1261 / 138 / 290 ) » 09.01.2020 13:36

Stimmt, man kann ja bei FOR auch eine WHERE-Bedingung angeben. Dann würde man da wohl auch mit CORRESPONDING oder händischer Spaltenangabe weiterkommen, wenn die Spalten der beiden beteiligten Tabellen nicht alle gleich sind.

Seite 1 von 1