Code: Alles auswählen.
MOVE-CORRESPONDING p0001 TO ausgabe.
SORT p2011 BY ldate ltime.
LOOP AT p2011 WHERE ldate > '20181231'.
CLEAR: ausgabe-backupgehzeit, ausgabe-rechenergebnis, ausgabe-zwischensumme, ausgabe-tagesarbeitszeit.
MOVE p2011-ldate TO ausgabe-datum.
CASE p2011-satza.
WHEN 'P10'. MOVE p2011-ltime TO ausgabe-kommzeit. MOVE ausgabe-kommzeit TO ausgabe-backupkommzeit.
WHEN 'P20'. MOVE p2011-ltime TO ausgabe-gehzeit. MOVE ausgabe-gehzeit TO ausgabe-backupgehzeit. CLEAR: ausgabe-kommzeit, ausgabe-gehzeit, ausgabe-kurzbeschreibung.
WHEN '02'. MOVE p2011-ltime TO ausgabe-gehzeit. MOVE ausgabe-gehzeit TO ausgabe-backupgehzeit. CLEAR: ausgabe-kommzeit, ausgabe-gehzeit, ausgabe-kurzbeschreibung. MOVE 'ohne Pause' TO ausgabe-kurzbeschreibung.
ENDCASE.
CHECK ausgabe-backupgehzeit NE '000000'.
ausgabe-rechenergebnis = ausgabe-backupgehzeit - ausgabe-backupkommzeit.
MOVE ausgabe-backupkommzeit TO ausgabe-kommzeit.
MOVE ausgabe-backupgehzeit TO ausgabe-gehzeit.
MOVE ausgabe-rechenergebnis TO ausgabe-zwischensumme.
" ausgabe-tagesarbeitszeit = ausgabe-zwischensumme + ausgabe-rechenergebnis.
APPEND ausgabe.
Code: Alles auswählen.
rechenergebnis [T(6)]
Folgende Benutzer bedankten sich beim Autor wreichelt für den Beitrag:
Florian9999
Code: Alles auswählen.
DATA: BEGIN OF ausgabe OCCURS 0,
personalnr(8) TYPE c,
END OF ausgabe.
Code: Alles auswählen.
COLLECT ausgabe-rechenergebnis INTO ausgabe-personalnr.
Er könnte die Spalten auch drinlassen, das wäre überhaupt kein Problem, wenn er nicht einen Codingstil von Release 3.1 (oder noch früher) schreiben würde! Der COLLECT orientiert sich am Primärschlüssel der Tabelle. Wenn er seine Tabelle ausgabe mit einem unique key pernr definieren würde, dann würde der COLLECT darüber aufsummieren, egal was da noch an anderen Feldern da ist. Optimalerweise als sortierte oder Hashtabelle, dann wird der COLLECT gleich noch performanter (und der spätere Zugriff auf die Ergebnistabelle auch). Dazu müsste er sich freilich von der vorsintflutlichen Tabellendefinition über OCCURS 0 verabschieden. Auch von den ganzen MOVEs kriegt man Augenkrebs; nach meiner Erinnerung waren die zu 3.1i-Zeiten bereits deprecated. Vor allem der verwirrende Ketten-MOVE
Code: Alles auswählen.
MOVE p2011-ltime TO ausgabe-kommzeit. MOVE ausgabe-kommzeit TO ausgabe-backupkommzeit.
Code: Alles auswählen.
ausgabe-kommzeit = ausgabe-backupkommzeit = p2011-ltime.
Folgende Benutzer bedankten sich beim Autor DeathAndPain für den Beitrag:
Florian9999
ERP608 mit NW750 auf SP13
Code: Alles auswählen.
WHEN 'P20'. MOVE p2011-ltime TO ausgabe-gehzeit. MOVE ausgabe-gehzeit TO ausgabe-backupgehzeit. CLEAR: ausgabe-kommzeit, ausgabe-gehzeit, ausgabe-kurzbeschreibung.
Code: Alles auswählen.
TYPES: BEGIN OF TYPE_AUSGABE,
PERNR TYPE P2011-PERNR,
DATUM TYPE P2011-LDATE,
ENAME TYPE P0001-ENAME,
TAGESARBEITSZEIT TYPE P2011-LTIME,
* ... (add any desired additional fields here)
END OF TYPE_AUSGABE.
DATA: P0001 TYPE P0001,
T2011 TYPE SORTED TABLE OF P2011 WITH NON-UNIQUE KEY LDATE LTIME,
AUSGABE TYPE SORTED TABLE OF TYPE_AUSGABE WITH UNIQUE KEY PERNR DATUM,
WA_AUSGABE LIKE LINE OF AUSGABE.
* ... fill T2011 here
* SORT P2011 BY LDATE LTIME. " entfällt, da Tabelle bereits als SORTED definiert und daher automatisch immer sortiert ist
LOOP AT T2011 ASSIGNING FIELD-SYMBOL(<T2011>) WHERE LDATE > '20181231'. " LOOP sucht effizient, da er erkennt, dass seine WHERE-Bedingung mit dem Anfang des Primärschlüssels von T2011 übereinstimmt
* Zeile in Tabelle ausgabe für diese Personalnummer und diesen Tag suchen (unter Nutzung des Sortierschlüssels)
ASSIGN AUSGABE[ PERNR = <T2011>-PERNR DATUM = <T2011>-LDATE ] TO FIELD-SYMBOL(<AUSGABE>).
IF SY-SUBRC <> 0. " Gibt es noch keinen Eintrag für diese Personalnummer und dieses Datum?
INSERT VALUE #( PERNR = <T2011>-PERNR
DATUM = <T2011>-LDATE
ENAME = P0001-ENAME
TAGESARBEITSZEIT = <T2011>-ENDUZ - <T2011>-BEGUZ " Arbeitszeit dieses T2011-Eintrags berechnen
* ... (fill any desired additional fields here)
) INTO TABLE AUSGABE. " sortiert einfügen (Sortierung erfolgt automatisch anhand des Tabellenschlüssels)
ELSE.
<AUSGABE>-TAGESARBEITSZEIT = <AUSGABE>-TAGESARBEITSZEIT + <T2011>-ENDUZ - <T2011>-BEGUZ. " Das Feldsymbol <AUSGABE> zeigt direkt auf die Tabellenzeile. Wir brauchen also keinen MODIFY-Befehl mehr.
ENDIF.
ENDLOOP.
DeathAndPain hat geschrieben: ↑29.05.2019 14:36Wenn Du gerade erst anfängst, wer hat Dir denn dann diese antike Syntax beigebracht? Hast Du ein altes ABAP-Buch auf dem Speicher gefunden?
Hier steht die Art der Stempelung drin. P10 für kommen; P20 für gehen und 02 für gehen ohne Pause.DeathAndPain hat geschrieben: ↑29.05.2019 14:36Mir ist aber auch nicht klar, was Du da mit dem P2011-SATZA machst.
Ich habe P2011-LTIME verwendet um nach P2011-SATZA Gehen normal und Gehen ohne Pause sortieren zu können. Daraufhin läuft die Auswertung hinaus, später.DeathAndPain hat geschrieben: ↑29.05.2019 14:36Wir nutzen hier den Infotyp 2011 nicht, deswegen habe ich keine Beispielzeilen dieser Tabelle vorzuliegen, sondern nur ihre Definition laut SE11, aber ich sehe da als wesentliche Felder P2011-BEGUZ und P2011-ENDUZ (Beginn- und Endeuhrzeit) und würde in meiner Naivität vermuten, dass jede Zeile ein Stechuhreintrag ist und sich die Arbeitszeit eines solchen Stechuhreintrags nicht wie in Deinem Code angegeben, sondern aus P2011-ENDUZ minus P2011-BEGUZ errechnet?
Ja, genau. So siehts m.E. nach aus.DeathAndPain hat geschrieben: ↑29.05.2019 14:36Wenn die Ermittlung über die P2011-SATZA in Deinem Code richtig wäre, dann würde das ja bedeuten, dass Beginn- und Endezeit derselben Arbeitszeit in unterschiedlichen P2011-Zeilen liegen.
Chronologisch.DeathAndPain hat geschrieben: ↑29.05.2019 14:36Wenn jemand mehrfach am Tag ein- und ausstempelt, wäre dann die Frage, wie Du die richtige Paarung der Zeilen hinbekommst, welches Einstempeln also zu welchem Ausstempeln gehört. Oder geht das einfach chronologisch (erstes Ausstempeln gehört zum ersten Einstempeln usw.)
Für die ALV-Ausgabe.DeathAndPain hat geschrieben: ↑29.05.2019 14:36Aber wozu braucht man dann P2011-BEGUZ und P2011-ENDUZ?
Danke!DeathAndPain hat geschrieben: ↑29.05.2019 14:36Ich bin mal von meiner Theorie ausgegangen und habe Dein Coding basierend darauf ohne COLLECT umgestaltet und dabei die moderne, ab Release 7.40 erlaubte Syntax genutzt. Das sieht dann so aus:
So richtig habe ich das nicht verstanden. Wenn Ein- und Ausstempeln unterschiedliche P2011-Einträge erzeugen (also vermutlich die Stechuhr bei jedem Stempeln eine Zeile anlegt), wie werden dann BEGUZ und ENDUZ gefüllt? "Merkt" die Stechuhr sich die Einstempelzeit, und trägt diese beim Ausstempeln dann als "BEGUZ" ein? Es wäre hilfreich, wenn Du per SE16 mal ein paar (anonymisierte) Beispielzeilen der PA2011 posten könntest, damit ich ein Gefühl dafür kriege, was in der Tabelle überhaupt genau drinsteht.Ich habe P2011-LTIME verwendet um nach P2011-SATZA Gehen normal und Gehen ohne Pause sortieren zu können. Daraufhin läuft die Auswertung hinaus, später.
Bei P2011-BEGUZ und P2011-ENDUZ könnte ich das m.E. nach nicht?
Code: Alles auswählen.
*&---------------------------------------------------------------------*
*& Report ZTEST6
*&---------------------------------------------------------------------*
REPORT ZTEST6.
TYPES: BEGIN OF TYPE_AUSGABE,
PERNR TYPE P2011-PERNR,
DATUM TYPE P2011-LDATE,
ENAME TYPE P0001-ENAME,
TAGESARBEITSZEIT TYPE P2011-LTIME,
SATZA TYPE P2011-SATZA,
* ... (add any desired additional fields here)
END OF TYPE_AUSGABE.
DATA: P0001 TYPE P0001,
T2011 TYPE SORTED TABLE OF P2011 WITH NON-UNIQUE KEY PERNR LDATE LTIME,
AUSGABE TYPE SORTED TABLE OF TYPE_AUSGABE WITH UNIQUE KEY PERNR DATUM,
KOMMZEIT TYPE P2011-LTIME.
* ... fill T2011 here
* SORT P2011 BY LDATE LTIME. " entfällt, da Tabelle bereits als SORTED definiert und daher automatisch immer sortiert ist
LOOP AT T2011 ASSIGNING FIELD-SYMBOL(<T2011>) WHERE PERNR = P0001-PERNR
AND LDATE > '20181231'. " LOOP sucht effizient, da er erkennt, dass seine WHERE-Bedingung mit dem Anfang des Primärschlüssels von T2011 übereinstimmt
IF <T2011>-SATZA = 'P10'.
KOMMZEIT = <T2011>-LTIME.
CONTINUE. " LOOP
ENDIF.
* Zeile in Tabelle ausgabe für diese Personalnummer und diesen Tag suchen (unter Nutzung des Sortierschlüssels)
ASSIGN AUSGABE[ PERNR = <T2011>-PERNR DATUM = <T2011>-LDATE ]-TAGESARBEITSZEIT TO FIELD-SYMBOL(<TAGESARBEITSZEIT>).
IF SY-SUBRC <> 0. " Gibt es noch keinen Eintrag für diese Personalnummer und dieses Datum?
INSERT VALUE #( PERNR = <T2011>-PERNR
DATUM = <T2011>-LDATE
ENAME = P0001-ENAME
TAGESARBEITSZEIT = <T2011>-LTIME - KOMMZEIT " Arbeitszeit berechnen
SATZA = <T2011>-SATZA " Gehen normal oder Gehen ohne Pause merken für spätere Auswertung
* ... (fill any desired additional fields here)
) INTO TABLE AUSGABE. " sortiert einfügen (Sortierung erfolgt automatisch anhand des Tabellenschlüssels)
ELSE.
<TAGESARBEITSZEIT> = <TAGESARBEITSZEIT> + <T2011>-LTIME - KOMMZEIT. " Das Feldsymbol <TAGESARBEITSZEIT> zeigt direkt auf das Feld in der Tabellenzeile. Wir brauchen also keinen MODIFY-Befehl mehr.
ENDIF.
ENDLOOP.