move itab 1 nach itab 2 mit bedingung

Getting started ... Alles für einen gelungenen Start.
31 Beiträge • Seite 1 von 3 (current) Nächste
31 Beiträge Seite 1 von 3 (current) Nächste

move itab 1 nach itab 2 mit bedingung

Beitrag von c oco (Specialist / 320 / 11 / 16 ) » 17.04.2012 14:39
Hallo,
ich möchte alle Datensätze die vgabe <> 9 sind in die zweite itab und diese dann aus der ersten itab löschen.
Mit loop ist es keine prozessoptimale Lösung.
Mit move kann ich keine Where Bedingung angeben.
Wisst ihr eine Möglichkeit?

Code: Alles auswählen.

 LOOP AT lt_le ASSIGNING <ls_le> WHERE vgabe <> '9'.
      IF sy-subrc = 0.
        APPEND <ls_le> TO lt_re.
        DELETE lt_le.
      ENDIF.
    ENDLOOP.
Viele Grüße
coco


Re: move itab 1 nach itab 2 mit bedingung

Beitrag von ratsnus (Specialist / 352 / 2 / 53 ) » 17.04.2012 15:43
hmm hab zwar noch nie damit gearbeitet, aber es gibt doch für interne Tabellen noch den "provide" Befehl wo man eine where Bedingung nutzen kann, villeicht hilft dir das ja.

gruss
ratsnus
<:: XING-Gruppe Tricktresor::>

Re: move itab 1 nach itab 2 mit bedingung

Beitrag von c oco (Specialist / 320 / 11 / 16 ) » 17.04.2012 17:20
Hallo ratsnus,

danke für deine Antwort.
Bei dem Befehl provide ist in der F1 Hilfe eine Anmerkung
Diese Anweisung sollte nur von Spezialisten verwendet werden.
Eine profunde Kenntnis des zugehörigen Umfelds ist unerlässlich.
Dieses Umfeld ist nicht Teil von ABAP und hier nicht dokumentiert.
hat mich bissle abgeschreckt, wobei ich mir nicht vorstellen kann, was da schlimmes passieren soll wenn man nur abfragen macht und das Befehl sich auf interne Tabellen bezeiht.

Manchmal ist die Lösung so einfach und ist performanter.

Code: Alles auswählen.

 SORT lt_le BY vgabe DESCENDING.
    lt_re = lt_le.
    delete lt_le where vgabe <> '9'.
    delete lt_re where vgabe = '9'.
Viele Grüße
coco

Re: move itab 1 nach itab 2 mit bedingung

Beitrag von a-dead-trousers (Top Expert / 3539 / 115 / 919 ) » 18.04.2012 08:32
<Klugscheissermodus>
IMHO ist das nicht der performanteste Ansatz. Vor allem wenn du sehr viele Datensätze hast.
Das sollte um einiges performanter sein

Code: Alles auswählen.

SORT lt_le BY vgabe.
READ TABLE lt_le TRANSPORTING NO FIELDS BINARY SEARCH WITH KEY vgabe = '9'.
IF sy-subrc EQ 0.
  ld_index = sy-tabix.
  LOOP AT lt_le ASSIGNING <ls_le> FROM ld_index.
    IF <ls_le>-vgabe NE '9'.
      EXIT.
    ENDIF.
    APPEND <ls_le> TO lt_re.
    DELETE lt_le.
  ENDLOOP.
ENDIF.
Damit werden keine Datensätze dupliziert und das BINARY SEARCH macht die Suche sehr effizient. Ein Index-Zugiff ist bei Tabellen (mit Ausnahme HASHED) immer die schnellste Art Daten zu lesen.

Code: Alles auswählen.

LOOP AT lt_le ASSIGNING <ls_le> WHERE vgabe EQ '9'.
  APPEND <ls_le> TO lt_re
  DELETE lt_le.
ENDLOOP.
Das wäre der "einfache" Ansatz ebenfalls ohne die Daten zu duplizieren, aber mit einer imperformanten Suche über alle Zeilen (bei Verwendung von WHERE müssen alle Zeilen geprüft werden). Alternativ könnte man eine SORTED Tabelle verwenden, da verliert man aber beim Einfügen evtl. an Performance.

Man müsste beide Varianten gegeneinander antreten lassen um festzustellen ob mit sort/binary search bessere Ergebnisse möglich sind als mit einer Suche über alle Zeilen. Kommt wie gesagt auf die Datenmenge bzw. die Fragmentierung an.
</Klugscheissermodus>

lg ADT

EDIT: Okay, hab grad gemerkt, dass eigentlich die ungleich '9' in die andere Tabelle sollen. Bei meinen beiden Varaianten habe ich einfach (aus performance Gründen) die Tabellen vertauscht (EQ ist besser als NOT EQ).
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.07
Basis: 7.40

Re: move itab 1 nach itab 2 mit bedingung

Beitrag von c oco (Specialist / 320 / 11 / 16 ) » 18.04.2012 10:18
Hallo ADT,

vielen Dank für den "Klugscheissermodus" :-). Ist wie du sagst performanter und ich habe es eingebaut.
Da ich genau dieses Ziel, (nämlich performanter zu lesen) verfolgte, ist der "Klugscheissermodus" sehr willkommen.

Viele Grüße
coco

Re: move itab 1 nach itab 2 mit bedingung

Beitrag von black_adept (Top Expert / 3424 / 67 / 665 ) » 18.04.2012 13:15
@ADT
Du gehst nur den halben Weg. Wenn schon der Ansatz via SORT und BINARY SEARCH gewählt wird, sollten danach dann die Befehlszusätze für blockweises Löschen und Appendieren verwendet werden. Das sollte noch mal deutlich schneller sein.

@c oco
Die ganze Diskussion um die Laufzeit sieht in meinem Augen wie Schmuck am Nachthemd aus. Könntest du mal den realen Laufzeitunterschiede zwischen deinen beiden Versionen in deinem ersten Posting und der letzten Version von adt posten? ( am besten über ein paar Versuche gemittelt). Ich kann mir momentan gar nicht vorstellen, dass der erzielte Laufzeitgewinn den Komplexitätszuwachs des Codings aufwiegt. Und schlussendlich: Wieviel % und absolut wird denn das Gesamtprogramm schneller durch die Änderung?
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: move itab 1 nach itab 2 mit bedingung

Beitrag von a-dead-trousers (Top Expert / 3539 / 115 / 919 ) » 18.04.2012 13:50
black_adept hat geschrieben:Befehlszusätze für blockweises Löschen und Appendieren verwendet werden.
Jetzt oute ich mich mal als unwissender. Welche meinst du?
black_adept hat geschrieben:Die ganze Diskussion um die Laufzeit sieht in meinem Augen wie Schmuck am Nachthemd aus.
Das finde ich nicht. Nicht umsonst gibts von SAP die Schulung BC 490.
Bevor ich die Schulung gemacht hab, bin ich in Codings öfters über den Aufbau mit SORT/READ TABLE/LOOP AT gestolpert und mich immer gefragt "Warum so kompliziert?" Aber seit der Schulung bin ich da anderer Meinung :P
Es gibt einige gute Tricks mit denen man die Performance von Programmen radikal verbessern kann.

Bestes Beispiel hab ich in IS-H*MED (Hospital) entdeckt. Da werden sog. Dokumenttypen ausgelesen und intern werden dann die Werte spezifiziert. Im Durchschnitt so ca. 100 Zeilen lange Tabellen werden da mehrmals mit LOOP AT INTO und MODIFY durchalufen. Hab mir das vorgenommen und nur durch LOOP AT ASSIGNING ersetzt. Das Ding war um den FAKTOR 10 schneller.
Bei einer Aufrufzeit von 1 sek. mag das nicht soviel erscheinen, aber rechne mal das hoch wenn du hintereinander 10 verschiedene Dokumenttypen öffnen willst.

Anderes Beispiel: Optimale Nutzung von Indizes. Es ist oft schlechter ZUVIELE Parameter bei einem SELECT anzugeben. z.b. über einen aufwändigen Selektionsschirm. Wenn man nun eine SELECT-OPTION nicht befüllt hat aber trotzdem an das SELECT übergibt, kann es vorkommen das dadurch ein viel schlechterer Index gewählt wird, obwohl mit den anderen Daten ein besserer möglich wäre. In dem Fall muss man je nach versorgten Parametern ein anderes SELECT-Statement verwenden.

lg ADT
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.07
Basis: 7.40

Re: move itab 1 nach itab 2 mit bedingung

Beitrag von a-dead-trousers (Top Expert / 3539 / 115 / 919 ) » 18.04.2012 13:54
a-dead-trousers hat geschrieben:
black_adept hat geschrieben:Befehlszusätze für blockweises Löschen und Appendieren verwendet werden.
Jetzt oute ich mich mal als unwissender. Welche meinst du?
Ach: DELETE ... FROM ... TO ... und INSERT LINES OF ... FROM ... TO ... INTO TABLE ... usw.
Die hatte ich vergessen :oops:
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.07
Basis: 7.40

Re: move itab 1 nach itab 2 mit bedingung

Beitrag von black_adept (Top Expert / 3424 / 67 / 665 ) » 18.04.2012 14:55
a-dead-trousers hat geschrieben: Das finde ich nicht. Nicht umsonst gibts von SAP die Schulung BC 490....
lg ADT
Die Aussage bezog sich nicht auf LZ-Optimierungen allgemein, sondern auf diesen speziellen Fall. Wenn der LZ-Unterschied eklatant ist, bin ich ein eifriger Verfechter auch hinreichend komplexer Codings um dies zu bewerkstelligen.

Wenn sich aber am Ende herausstellt, dass die Optimierung ( hier die Partitionierung einer Tabelle in 2 disjunkte Teiltabellen ) zwar in seiner Laufzeit um den Faktor 5 beschleunigt werden konnte, aber die Paritionierung nur 1% der Gesamtlaufzeit ausgemacht hat, sprechen wir von einem Gesamtgewinn von ~0,8%.
Daher meine Frage an c oco, wieviel der Gesamtlaufzeit denn von der hier angesprochenen Codingpassage real verbraten wird. Ich kenne zwar durchaus Szenarien, wo das relevant sein könnte - aber das sind eher die Ausnahmen. In den meisten mir bisher untergekommenen Fällen ist das nicht der Laufzeitfresser.
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: move itab 1 nach itab 2 mit bedingung

Beitrag von a-dead-trousers (Top Expert / 3539 / 115 / 919 ) » 19.04.2012 08:08
Jedes bisschen an Performance rauszuquetschen ist IMHO kein schlechter Ansatz.
Ich geb schon zu, dass es vielleicht nur für diesen einen Abschnitt im Programm nicht viel Sinn machen wird.
Ich denke aber, dass durch Aufzeigen wie man es "besser" machen kann, man dieses optimierte (und von SAP geschulte) Vorgehen vielleicht an anderen Stellen wiederverwenden kann.
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.07
Basis: 7.40

Re: move itab 1 nach itab 2 mit bedingung

Beitrag von Stegemann90 (ForumUser / 31 / 3 / 0 ) » 01.07.2015 08:48
Hallo zusammen!

Habe ein ähnliches Problem und hoffe das ihr mir helfen könnt:

Ich importe einen Datensatz mit ca. 1000 Zeilen in eine ITAB (ITAB1).

Damit ich diese per Bapi verarbeiten kann, muss ich nun die ersten 100 Zeilen in eine ITAB2 überführen, die ich dann wiederum per Bapi verarbeite... Darufhin sollen die Daten aus Itab2 gelöscht werden und die nächsten 100 Zeilen aus ITAB1 übertragen werden usw usw... Habt ihr da evtl eine Lösung für?

Re: move itab 1 nach itab 2 mit bedingung

Beitrag von a-dead-trousers (Top Expert / 3539 / 115 / 919 ) » 01.07.2015 09:16

Code: Alles auswählen.

APPEND LINES OF itab1 TO 100 TO itab2.
DELETE itab1 TO 100.
Und das Ganze solange machen wie Zeilen in itab1 vorhanden sind.

(Ich hab deshalb den Code gleich gepostet, weil das mit den 2 TO hintereinander sonst etwas verwirrend zu verstehen/erklären ist, aber es funktioniert wirklich so)

lg ADT
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.07
Basis: 7.40

Re: move itab 1 nach itab 2 mit bedingung

Beitrag von Stegemann90 (ForumUser / 31 / 3 / 0 ) » 01.07.2015 09:57
wow, danke für die schnelle Antwort! das klingt erstmal logisch, habe es auch direkt eingebaut (nur ein Ausschnitt):

Code: Alles auswählen.

APPEND LINES OF ITAB1 TO 100 TO ITAB2.
DELETE ITAB1 TO 100.

LOOP AT ITAB2.
 CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
      input = ITAB2-WRBTR1
IMPORTING
      output = ITAB2-WRBTR1.
 CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
      input = ITAB2-WRBTR3
IMPORTING
      output = ITAB2-WRBTR3.
* Belegkopf
ls_doc_header-co_area     = ITAB2-KRKRS.         "Kostenrechnungskreis
ls_doc_header-docdate     = ITAB2-WRBTR10.          "Belegdatum
ls_doc_header-postgdate   = ITAB2-WRBTR11.       "Buchungsdatum
ls_doc_header-doc_hdr_tx  = ITAB2-BLTXT.         "Belegkopftext
ls_doc_header-username    = sy-uname.       "User-Name
* Positionen aufbauen
* Pos. 1
ls_doc_item-send_cctr     = ITAB2-WRBTR1.   "Sender-Kostenstelle
ls_doc_item-acttype       = ITAB2-WRBTR2.            "Leistungsart
ls_doc_item-actvty_qty    = ITAB2-WRBTR6.              "Menge
ls_doc_item-rec_cctr      = ITAB2-WRBTR3.   "Empfänger-KST
ls_doc_item-rec_order     = ITAB2-WRBTR4.   "Empfänger-Auftrag
ls_doc_item-rec_wbs_el    = ITAB2-WRBTR5.   "Empfänger-KTR
ls_doc_item-activityun    = ITAB2-WRBTR7.   "Leistungseinheit
ls_doc_item-person_no      = ITAB2-WRBTR8.   "Gerätebezeichnung
ls_doc_item-seg_text      = ITAB2-WRBTR9.   "Segmenttext
APPEND ls_doc_item TO lt_doc_items.
ENDLOOP.


* BAPI rufen
CALL FUNCTION 'BAPI_ACC_ACTIVITY_ALLOC_POST'
  EXPORTING
    doc_header      = ls_doc_header
*   IGNORE_WARNINGS = ' '
  IMPORTING
    doc_no          = ls_docno
  TABLES
    doc_items       = lt_doc_items
    return          = lt_return
*   CRITERIA        =
*   CUSTOMER_FIELDS =
  .

REFRESH ITAB2.

APPEND LINES OF ITAB1 TO 100 TO ITAB2.
DELETE ITAB1 TO 100.

LOOP at ITAB2.
 CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
      input = ITAB2-WRBTR1
IMPORTING
      output = ITAB2-WRBTR1.
 CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
      input = ITAB2-WRBTR3
IMPORTING
      output = ITAB2-WRBTR3.
* Belegkopf
ls_doc_header-co_area     = ITAB2-KRKRS.         "Kostenrechnungskreis
ls_doc_header-docdate     = ITAB2-WRBTR10.          "Belegdatum
ls_doc_header-postgdate   = ITAB2-WRBTR11.       "Buchungsdatum
ls_doc_header-doc_hdr_tx  = ITAB2-BLTXT.         "Belegkopftext
ls_doc_header-username    = sy-uname.       "User-Name
* Positionen aufbauen
* Pos. 1
ls_doc_item-send_cctr     = ITAB2-WRBTR1.   "Sender-Kostenstelle
ls_doc_item-acttype       = ITAB2-WRBTR2.            "Leistungsart
ls_doc_item-actvty_qty    = ITAB2-WRBTR6.              "Menge
ls_doc_item-rec_cctr      = ITAB2-WRBTR3.   "Empfänger-KST
ls_doc_item-rec_order     = ITAB2-WRBTR4.   "Empfänger-Auftrag
ls_doc_item-rec_wbs_el    = ITAB2-WRBTR5.   "Empfänger-KTR
ls_doc_item-activityun    = ITAB2-WRBTR7.   "Leistungseinheit
ls_doc_item-person_no      = ITAB2-WRBTR8.   "Gerätebezeichnung
ls_doc_item-seg_text      = ITAB2-WRBTR9.   "Segmenttext
APPEND ls_doc_item TO lt_doc_items.
ENDLOOP.


* BAPI rufen
CALL FUNCTION 'BAPI_ACC_ACTIVITY_ALLOC_POST'
  EXPORTING
    doc_header      = ls_doc_header
*   IGNORE_WARNINGS = ' '
  IMPORTING
    doc_no          = ls_docno
  TABLES
    doc_items       = lt_doc_items
    return          = lt_return
*   CRITERIA        =
*   CUSTOMER_FIELDS =
  .
Meiner Meinung nach müsste das Programm nun zwei Buchungen mit je 100 Sätzen erstellen. Das macht es aber leider nicht: Es erstellt eine erste Buchung mit den ersten 100 Datensätzen und eine zweite Buchung mit den ersten 200 Datensätzen (sodass di ersten 100 DS quasi doppelt gebucht werden).

Kannst du mir da vll noch einmal weiterhelfen? Vielen Dank schon mal vorab!

Re: move itab 1 nach itab 2 mit bedingung

Beitrag von JHM (Top Expert / 1139 / 1 / 179 ) » 01.07.2015 10:07
Stegemann90 hat geschrieben:Kannst du mir da vll noch einmal weiterhelfen?
Du musst nach dem ersten BAPI-Call nicht nur itab2 sondern auch die BAPI-Tabellen (lt_doc_items) löschen/refreshen/clearen.
Gruß Hendrik

Re: move itab 1 nach itab 2 mit bedingung

Beitrag von Dele (Specialist / 307 / 4 / 47 ) » 01.07.2015 10:08
Du musst lt_doc_items vor dem zweiten füllen ebenfalls refreshen.


Vergleichbare Themen

Select mit itab in where-Bedingung
von fcmfanswr » 14.07.2011 10:29
delete from itab mit where Bedingung
von debianfan » 31.07.2019 14:38
XML->ITAB
von ewx » 09.07.2008 10:24
XML to itab
von Drogbar » 12.01.2006 12:56
itab in itab
von dimes » 07.02.2007 12:27