interne Tabelle durchsuchen

für eilige Fragen
15 Beiträge • Seite 1 von 1
15 Beiträge Seite 1 von 1

interne Tabelle durchsuchen

Beitrag von Spookykid (Specialist / 140 / 28 / 0 ) »
Hallo,

ich habe eine CSV Datei aus einem System extrahiert und dies in ein anderes importiert und in eine interne Tabelle geschrieben. Nun will ich die CSV Datei mit einer Tabelle des DDIC abgleichen, wobei die CSV die Basis sein soll. Ich habe es mit einem Select versucht, geht ja aber leider nicht auf interne Tabellen. Kann mir jemand helfen, ich stehe etwas auf dem Schlauch.

Vielen Dank im Voraus!

gesponsert
Stellenangebote auf ABAPforum.com schalten
kostenfrei für Ausbildungsberufe und Werksstudenten


Re: interne Tabelle durchsuchen

Beitrag von casman (Specialist / 420 / 1 / 63 ) »
Kommt drauf an, was du jetzt genau rausbekommen willst, aber ich prinzipiell kannst du:
- die DDIC-tab auch in eine intere lesen und dann per LOOP AT oder READ TABLE mit der CSV vergleichen, dir Einträge merken, löschen etc.
- die CSV mit LOOP AT durchlaufen und per SELECT SINGLE die Datensätze der DDIC überprüfen (Achtung: Performance)

Re: interne Tabelle durchsuchen

Beitrag von Spookykid (Specialist / 140 / 28 / 0 ) »
ok, ich habe in meinem initial post nicht exakt formuliert. ich habe die csv in eine interne tab geschrieben und möchte diese nun mit einer DDIC- Tabelle vergleichen. Ich werde es mal mit dem READ Befehl probieren. Hast du noch weitere Vorschläge? Wie kann ich interne Tabelle vergleichen, wenn ich den Zusatz "'WITH HEADER LINE" bei der Deklaration weg lasse? Muss ich immer den Umweg mit der Workarea gehen?

Viele Grüße

Re: interne Tabelle durchsuchen

Beitrag von casman (Specialist / 420 / 1 / 63 ) »
Hi,

also in einem ersten Schritt kannst du folgende Prüfung machen:

if itab1[] = itab2[].
->alles ok
endif.

Das funktioniert aber nur, wenn beide Tabellen total identisch sind.

Jetzt kommt es drauf an, ob du wissen willst:
- alle Einträge aus ITAB1, die nicht in ITAB2 sind
- alle Einträge aus ITAB2, die nicht in ITAB1 sind
- alle Unterschiede
-> Je nachdem musst du 1-2 mal durchloopen.

Und wenn du keine Kopfzeile hast, musst du immer eine Workarea nutzen. Die Workarea ist nichts anderes als eine explizite Kopfzeile, während die Deklaration mit HEADER LINE eine implizite Kopfzeile erzeugt.
Verwende beim loopen LOOP AT ASSIGNING, das ist performant.

Re: interne Tabelle durchsuchen

Beitrag von ralf.wenzel (Top Expert / 3946 / 201 / 281 ) »
casman hat geschrieben:Und wenn du keine Kopfzeile hast, musst du immer eine Workarea nutzen.
Hä?
casman hat geschrieben:Die Workarea ist nichts anderes als eine explizite Kopfzeile, während die Deklaration mit HEADER LINE eine implizite Kopfzeile erzeugt.
Aha. Man sollte vllt. über die mannigfachen Nachteile von Tabellen mit Kopfzeilen was sagen, wenn man sie schon erwähnt. Nicht umsonst sind sie im OO-Kontext verboten.
casman hat geschrieben:Verwende beim loopen LOOP AT ASSIGNING, das ist performant.
Und was soll er dann bitte mit einer Kopfzeile, wenn er eh den Zeiger durch den Tabellenkörper schickt? Warum sagst du nicht dazu, dass er dann ein Feldsymbol braucht und was das ist?


Ralf
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: interne Tabelle durchsuchen

Beitrag von casman (Specialist / 420 / 1 / 63 ) »
@ralf: Meine Güte hast ja Recht. :D
War schon aufm Sprung gen Heimat und hab nur halb nachgedacht. Allerdings setze ich auch voraus, dass man mit einem Hinweis auf einen Befehl sich mal selbst informieren kann. Sonst komm ich beim Erklären vom 100 ins 1000.

Also ich versuchs nochmal langsam:

WITH HEADER LINE
Mit dem Zusatz WITH HEADER LINE deklarierst du zusätzlich zur internen Tabelle implizit ein Datenobjekt, das den Zeilentyp der internen Tabelle hat, nämlich eine Kopfzeile der internen Tabelle und welches genauso heißt, wie deine Tabelle. Diese dient bei Operationen mit der internen Tabelle als Arbeitsbereich. Probleme dabei:
- ABAP interpretiert den Namen prinzipiell erstmal als Kopfzeile und nicht als die interne Tabelle
- Tabelle und Arbeitsbereich sind vom Namen her schwer unterscheidbar
- interne Tabellen dürfen bei der Schachtelung in Strukturen oder andere interne Tabellen keine Kopfzeilen haben, da dies zu zweideutigen Ausdrücken führt
Also nur explizite Kopfzeilen = Workareas verwenden.

FELDSYMBOLE
Im Grunde genommen sind Feldsymbole vergleichbar mit dereferenzierten Zeigern in der Sprache C. Sie zeigen auf ein Datenobjekt und ermöglichen so eine große Flexibilität bei der Adressierung von Datenobjekten.

Was ist nun der Unterschied zwischen Workarea und Feldsymbol?

Code: Alles auswählen.

LOOP AT itab INTO workarea.
Hier nutzt du die explizite Workarea, die Einträge der Tabelle werden mit jedem Durchlauf in den Arbeitsbereich kopiert. Dies kann mitunter sehr inperformant sein. Um die Tabelle z.B. zu ändern, musst du die Einträge der Workarea ändern und die Tabelle per MODIFY anpassen.

Code: Alles auswählen.

LOOP AT itab ASSIGNING <FS>.
Hier durchläufst du die Tabelle, das Feldsymbol zeigt jeweils nur auf deinen aktuellen Datensatz. Es findet also kein Transport der Werte statt (sehr performant) , allerdings wirkt sich eine Wertänderung des Feldsymbols direkt auf die interne Tabelle aus, also Vorsicht.


Du brauchst also nicht IMMER eine Workarea, sondern nur, wenn du nicht mit Feldsymbolen arbeitest und auf einzelne Datensätze der Tabelle zugreifen willst.

@ralf: Weitere Erläuterungen deinerseits sind gern gesehen. :wink:

Re: interne Tabelle durchsuchen

Beitrag von Spookykid (Specialist / 140 / 28 / 0 ) »
Vielen Dank für die Erläuterungen. Ich werde mich jetzt an die Arbeit machen und die Vorschläge umsetzen. Zwei Fragen noch:

1. ist tab1 = tab2 das gleich wie tab1[] = tab2[]? (Was bedeuten die eckigen Klammern? Haben wohl nichts mit arrays zu tun, oder?)
2. Ist in Abap der Vergleichs- und Zuweisungsoperator identisch?

Grüße

Re: interne Tabelle durchsuchen

Beitrag von casman (Specialist / 420 / 1 / 63 ) »
Hi spookykid,

ok, das [] enstammt leider noch meinem Post der internen Tabellen mit Kopfzeilen. Stell dir vor, du hast zwei interne Tabellen mit Kopfzeile, dann vergleicht:
- itab1 = itab2 die Kopfzeilen
- itab1[] = itab2[] die internen Tabellen

ABAP interpretiert also den reinen Namen der Tabelle mit Kopfzeile als Kopfzeile und bei [] den Namen als Tabellenkörper. Wenn du also explizite Workareas nutzt, dann brauchst du die Klammern nicht.

Der Operator = kann in ABAP zwei Funktionen erfüllen, einmal den arithmetischen Operator (Zuweisung) und einmal den arithmetischen Vergleichsoperator. Der Sinn ergibt sich aus dem Kontext, also wäre z.B.
- itab1 = itab2. eine Zuweisung und
- if itab1 = itab2. ein Vergleich
Alternativ kannst du den Vergleichsoperator auch im Format EQ (equals) angeben, also if itab1 EQ itab2.

Folgende Benutzer bedankten sich beim Autor casman für den Beitrag:
Spookykid


Re: interne Tabelle durchsuchen

Beitrag von ralf.wenzel (Top Expert / 3946 / 201 / 281 ) »
Es ist genau dann das gleiche, wenn du nicht mit Kopfzeile arbeitest. Bei einer Deklaration

data: tab1 ..... with header-line

ist tab1 immer die Kopfzeile und tab1[] immer der Tabellenkörper. Das ist einer der vielen Gründe, warum man sowas nicht tut. Spätestens beim clear musst du genau wissen, was du tust.
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: interne Tabelle durchsuchen

Beitrag von black_adept (Top Expert / 4106 / 129 / 945 ) »
Hallo spookykid,

auch wenn dir nun mehrfach (völlig zutreffend) gesagt wurde, dass du möglichst keine Tabellen mit Kopfzeilen anlegen sollst. Schau dir trotzdem an was passiert wenn du doch mit Kopfzeilen arbeitest.
Denn leider zwingt dich SAP manchmal dazu mit Kopfzeilen arbeiten zu müssen.
Beispiel wäre eine Methode die eine Rangetabelle als Parameter erwartet welchen du mit einer durch eine SELECT-OPTION definierte Rangetabelle füllen möchtest.
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: interne Tabelle durchsuchen

Beitrag von Spookykid (Specialist / 140 / 28 / 0 ) »
Vielen Dank euch beiden. Ich habe mal meine Applikationslogik geschrieben. Könnt ihr mir hierzu noch Verbesserungsvorschläge geben? Gerade mit den SKIP LINE TO ... Befehlen bin ich nicht wirklich glücklich.

Code: Alles auswählen.

TYPES: BEGIN OF ty_itab,
        posid TYPE prps-posid,
        objnr TYPE prps-objnr,
        prart TYPE prps-prart,
        stat TYPE jest-stat,
       END OF ty_itab.

data: lt_itab TYPE TABLE OF ty_itab,
p_filename TYPE FILENAME-FILEINTERN,
wa_itab Type ty_itab,
*Tables
lt_xpa Type TABLE OF ty_itab, lt_erg type TABLE OF ty_itab.

FIELD-SYMBOLS: <z1> TYPE ty_itab, <z2> Type ty_itab, <z3> like LINE OF lt_erg.


START-OF-SELECTION.

  PERFORM sub_get_filename .
  PERFORM sub_get_data .

* Tabelle aus dem Dictionary in interne Tabelle laden.
  SELECT prps~posid prps~objnr prps~prart jest~stat
    FROM prps JOIN jest on prps~objnr = jest~objnr
    into CORRESPONDING FIELDS OF TABLE lt_xpa
    WHERE jest~inact <> 'X'.


* Zeileninhalt der Tabelle lt_itab (Basis) auf Zeileninhalt mit Tabelle lt_xpa überprüfen.
  loop at lt_itab ASSIGNING <z1>.
    loop at lt_xpa ASSIGNING <z2>.
* Identifizierendes Objekt ist Feld objnr.
* Bei ungleichem Inhalt des Feldes stat wird dieser Datensatz in die Tabelle lt_erg geschrieben.
      if  <z1>-objnr = <z2>-objnr AND <z1>-stat <> <z2>-stat.
* Die Stati in der XPA sind andere als in der X82, deshalb müssen die "gleichbedeutenden" übersprungen werden.
        if <z1>-stat = 'E0002' AND <z2>-stat = 'I0002'.
          skip to line 64 .
        endif.
        IF <z1>-stat = 'E0003' AND <z2>-stat = 'I0045'.
          skip to line 64.
        endif.
        Append <z2> to lt_erg.
      endif.
    endloop.
  endloop.
  
*  loop at lt_erg ASSIGNING <z3>.
    
    
  
  


  PERFORM feldkatalog_fuellen.
  PERFORM fieldcatalog_commit.
  PERFORM alv_fill.

  clear: lt_itab, lt_xpa, lt_erg.

END-OF-SELECTION.

Re: interne Tabelle durchsuchen

Beitrag von casman (Specialist / 420 / 1 / 63 ) »
Sorry, ich verstehe grad nicht, was die SKIP TO LINE 64 bewirken/bewirken sollen?

Ansonsten kannst du deinen 2 Loop z.B. verringern, indem du bereits einschränkst:

Code: Alles auswählen.

loop at lt_itab ASSIGNING <z1>.
    loop at lt_xpa ASSIGNING <z2>
       WHERE   objnr = <z1>-objnr AND stat <> <z1>-stat.

Re: interne Tabelle durchsuchen

Beitrag von Spookykid (Specialist / 140 / 28 / 0 ) »
Die Skip TO Line 64 Anweisung soll gewährleisten, dass der Befehl "Append <z2> to lt_erg." nicht ausgefährt wird, sollten die beiden inneren Schleifen "true" sein.

Re: interne Tabelle durchsuchen

Beitrag von casman (Specialist / 420 / 1 / 63 ) »
Ok, SKIP TO LINE wird eigentlich für die Listausgabe benötigt und ist an dieser Stelle also nicht wirklich richtig.

Besser wäre, den aktuellen Schleifendurchlauf per

Code: Alles auswählen.

CONTINUE.
zu beenden, ABAP macht dann bei der nächsten Zeile weiter, oder im Bedarfsfall den Loop per
komplett zu beenden.

Achtung: CONTINUE bzw. EXIT wirken sich jeweils nur auf den LOOP aus, in dem sie stehen, also in deinem Fall nur auf den LOOP über lt_xpa.

Re: interne Tabelle durchsuchen

Beitrag von ralf.wenzel (Top Expert / 3946 / 201 / 281 ) »
Spookykid hat geschrieben:Die Skip TO Line 64 Anweisung soll gewährleisten, dass der Befehl "Append <z2> to lt_erg." nicht ausgefährt wird, sollten die beiden inneren Schleifen "true" sein.
Wow. Das erinnert mich an die Anweisung GOTO auf meinem ZX81 mit 1KB RAM, muss so Anfang der 80er gewesen sein..... ;)


Ralf
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Seite 1 von 1

Newsletter Anmeldung

Keine Beiträge verpassen! Wöchentlich versenden wir lesenwerte Beiträge aus unserer Community.
Die letzte Ausgabe findest du hier.
Details zum Versandverfahren und zu Ihren Widerrufsmöglichkeiten findest du in unserer Datenschutzerklärung.

Unbeantwortete Forenbeiträge

Bestellte Bestellpositionen
vor 47 Minuten von Manfred K. 1 / 6
MS-Word als Editor
Gestern von tekko 1 / 247
Formulare aus Fiori debuggen
vor 5 Tagen von Manfred K. 1 / 512