Zum Inhalt springen

ABAP auswertung logischer Datenbank


neinal

Empfohlene Beiträge

Hallo,

ich hab heute folgende Aufgabe bekommen:

Auswertungen mit der Logischen Datenbank PNPCE:

- wie viele Mitarbeiter gibt es? wie viele aktive Mitarbeiter gibt es?

- wie viel Prozent weibliche bzw. männliche Mitarbeiter gibt es?

- wie alt ist der älteste Mitarbeiter? wie alt ist der älteste Pensionist?

- wie alt sind die Mitarbeiter im Durchschnitt?

- wie viele Kinder haben die Mitarbeiter insgesamt? wie viele Mitarbeiter haben Kinder?

- was sind die beliebtesten Namen für die Kinder der Mitarbeiter?

da ich leider erst seit ein paar Wochen hier in der Firma bin und erst seit dem mit ABAP angefangen habe, tu ich mich etwas schwer. Ich probier schon seit einiger Zeit rum, aber komm nicht drauf, wie ich das am besten auswerten kann...

Habt ihr vielleicht einen Tipp oder Denkanstoß für mich? (Ich möchte keine volle Lösung haben...will ja bei der Sache auch was lernen und nicht nur stur abtippen/kopieren..^^)

Vielen Dank im Voraus.

Link zu diesem Kommentar
Auf anderen Seiten teilen

update:

ich hab jetzt funktionen gefunden... aber natürlich ist direkt ein neues problem aufgetaucht...

ich will mit dem befehl SELECT COUNT ( * ) auslesen, wie viele Mitarbeiter vorhanden sind. die tabelle, aber ich bekomm einen syntax-fehler :

" 'PERNR' ist im ABAP Dictionary nicht als Tabelle, Projektions- oder Datenbank-View deklariert.'

--> Pernr ist die Tabelle, aus der ich im Schritt vorher, die daten selektiert habe...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Update:

Hallo,

- wie viele Mitarbeiter gibt es? wie viele aktive Mitarbeiter gibt es?-> erledigt

- wie viel Prozent weibliche bzw. männliche Mitarbeiter gibt es? ?-> erledigt

- wie alt ist der älteste Mitarbeiter? wie alt ist der älteste Pensionist?

- wie alt sind die Mitarbeiter im Durchschnitt?

- wie viele Kinder haben die Mitarbeiter insgesamt? wie viele Mitarbeiter haben Kinder??-> Ausgabewert ist jeweils 7.. ich weiß, dass das falsch ist.. ich weiß aber nicht, was ich falsch mache...wahrscheinlich ist es aber wieder nur ein layer8 problem.. die tauchen heut ständig auf >.< ^^

- was sind die beliebtesten Namen für die Kinder der Mitarbeiter?-> erledigt, da in der Tabelle keine Namen der Kinder vorhanden sind

ich hab absolut nichts gefunden, womit ich das min, max, und den mittelwert errechnen kann...

das problem ist folgendes:

ich berechne das alter der mitarbeiter wie folgt:

* Ermitteln des Alters der Mitarbeiter

  alter = sy-datum - p0002-gbdat.

  DIVIDE alter BY 365.
meine erste idee war es das alter folgendermaßen zu behandeln:
  SELECT max( alter )                                   "Alter des ältesten Mitarbeiters

  INTO maxa

  FROM pa0002.

was natürlich nicht funktioniert.... (alter ist ja nunmal kein tabellenfeld)

nach langer langer suche im internet bin ich nun am verzweifeln.. ich finde absolut nichts, was mir weiter hilft...

leider programmieren meine mit-azubis zur zeit alle nur in java.. also kann mir da auch keiner helfen...

vielleicht habt ihr ja ideen oder tipps...

da ich nächste woche erstmal schule hab (blockunterricht) hoff ich darauf, dass sich in der woche jemand zu meinem thread verirrt, der weiß, was ich tun kann...

Bearbeitet von neinal
Link zu diesem Kommentar
Auf anderen Seiten teilen

Update:

leider programmieren meine mit-azubis zur zeit alle nur in java.. also kann mir da auch keiner helfen...

Mußt Du das in SQL machen? Das ABAP-SQL ist sehr speziell und unterscheidet sich stark vom Standard-SQL. ABAP ist sehr gewöhnungsbedürftig und altbacken, man kann da nicht elegant schachteln und casten wie z.B. in Java, sondern muß immer alles in skalare Zwischenvariablen oder flache Strukturen speichern. Von Java nach ABAP kommt mir immer vor wie der Wechsel vom PKW mit Bordcomputer zum Panzer fahren.

Dafür gibt es quasi als Entschädigung die mächtigen internen Tabellen und die perfekte Integrierung der Datenbank. Ich kenne deine logische Datenbank nicht. Aber versuche mal, eine Abfrage nur mit WHERE-Kriterien und Übergabe in eine interne Tabelle zu machen (into corresponding fields bzw move-corresponding). In der internen Tabelle kannst Du dann nach Herzenslust rechnen, sortieren, loopen und damit die gesuchten Werte berechnen.

Wenn Deine Aufgabenstellung ist, das unbedingt mit SQL zu machen, dann melde Dich noch mal, vielleicht kann ich Dir morgen in der Mittagspause helfen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mußt Du das in SQL machen? Das ABAP-SQL ist sehr speziell und unterscheidet sich stark vom Standard-SQL. ABAP ist sehr gewöhnungsbedürftig und altbacken, man kann da nicht elegant schachteln und casten wie z.B. in Java, sondern muß immer alles in skalare Zwischenvariablen oder flache Strukturen speichern. Von Java nach ABAP kommt mir immer vor wie der Wechsel vom PKW mit Bordcomputer zum Panzer fahren.

<flame>

Dafür funktioniert ABAP wenigstens.

</flame>

:D

Aber das ABAP auf OpenSQL setzt finde ich eigentlich sehr beruhigend. Denn damit ist die darunter liegende Datenbank völlig irrelevant.

@neinal:

Wäre es nicht cleverer, zunächt eine entsprechende Struktur / einen TYpen zu definieren, aus der pa0001 die Personalnummern pro Buchunkskreis / Meisterbereich / whatever auszulesen und in eine interne Tabelle gem. Sturktur (oder Typ) zu schreiben, über die ITab zu loopen und die weiteren Felder (Name, Geschlecht, Anzahl Kinder, ...) aus PA0002 und PA0021 auszulesen?

Im Anschluss reichen eigentlich schon die Zugriffe auf die ITab, um an die gewünschten Werte zu kommen.

Gruß

Micha

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es wäre wohl hilfreich, wenn neinal mal seinen bisherige Code in dem Zusammenhang postet mitsamt der Info, aus welchen Tabellen er nun welche Daten zusammensuchen möchte (ich selbst komme aus der MM / SD / Lagerverwaltungs - Ecke, kenne daher die Datenhaltung in HCM nicht), dann kann man nötigenfalls gemeinsam Hilfestellung leisten und einen kleinen Report zusammenbauen gemäß der Vorgehensweise die Micha vorgeschlagen hat.

Grüße

Alex

Link zu diesem Kommentar
Auf anderen Seiten teilen

1. vielen Dank für eure Antworten.

2. ich bin KEIN Kerl !!! ;)

3. poste ich euch hier einfach mal meinen Code.. ich werde nachher zwar noch Hilfe von jemandem aus meiner Abteilung bekommen, aber mal sehen, wie weit ich damit komme... Falls ich alles gelöst bekomme, sag ich aber nochmal Bescheid.

*&---------------------------------------------------------------------*

*& Report  Z_AUSWERTUNG

*&

*&---------------------------------------------------------------------*

*&

*& Report zum auswerten der logischen Datenbank PNPCE

*&---------------------------------------------------------------------*


REPORT  z_auswertung.



TABLES pernr.

NODES peras.

INFOTYPES: 0001,

           0002,                                    "Daten zur Person

           0021,                                    "Familie/Bezugsperson

           0704.                                    "Information Familienangehörige

DATA: anzm TYPE i,                                  "Anzahl Mitarbeiter

      anzam TYPE i,                                 "Anzahl aktive Mitarbeiter

      anzwe TYPE i,                                 "Anzahl weibliche Mitarbeiter

      anzma TYPE i,                                 "Anzahl männliche Mitarbeiter

      maxa TYPE i,                                  "Alter des ältesten Mitarbeiters

      maxapen TYPE i,                               "Alter des ältesten Pensionisten

      dsm TYPE i,                                   "Durchschnittsalter der Mitarbeiter

      anzk TYPE i,                                  "Anzahl Kinder insgesamt

      anzmk TYPE i,                                 "Anzahl Mitarbeiter mit Kind

      alter TYPE p.                                 "Alter des Mitarbeiters



  SELECT COUNT( DISTINCT pernr )                                "Anzahl Mitarbeiter

    INTO anzm

     FROM pa0002.



  SELECT COUNT( DISTINCT pernr )                                "Anzahl aktiver Mitarbeiter

    INTO anzam

    FROM pa0001

    WHERE persg = 1.



  SELECT COUNT( DISTINCT pernr )                                "Anzahl weiblicher Mitarbeiter

  INTO anzwe

  FROM pa0002

  WHERE gesch = 2.



  SELECT COUNT( DISTINCT pernr )                                 "Anzahl männlicher Mitarbeiter

   INTO anzma

   FROM pa0002

   WHERE gesch = 1.



  SELECT COUNT( DISTINCT pernr )                     "Anzahl der Mitarbeiter mit Kindern

  INTO anzmk

  FROM pa0002

  WHERE anzkd >= 1.


* Ermitteln des Alters der Mitarbeiter

  alter = sy-datum - p0002-gbdat.

  DIVIDE alter BY 365.


* ausgeben der Ergebnisse


  WRITE: / 'Anzahl Mitarbeiter:', anzm,

         / 'Anzahl aktiver Mitarbeiter:', anzam,

         / 'Anzahl weiblicher Mitarbeiter:', anzwe,

         / 'Anzahl männlicher Mitarbeiter:', anzma,

*         / 'Alter des ältesten Mitarbeiters:', maxa,

*         / 'Alter des ältesten Pensionisten:', maxapen,

*         / 'Durchschnittsalter der Mitarbeiter:', dsm,

         / 'Anzahl Kinder insgesam:', anzk,

         / 'Anzahl Mitarbeiter mit Kind:', anzmk.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Viele Wege führen nach Rom, sprich es gibt da mehrere Möglichkeiten zum Ziel zu kommen. Typischerweise benutzt man in ABAP nicht so sehr das Open-SQL (welches aus Kompatibilitätsgründen eine weitere Schicht über dem Datenbank-SQL ist, auf das Data Dictionary aufsetzt und nicht auf die Datenbank selbst, und der kleinste gemeinsame Nenner aller möglichen Datenbanksysteme ist) für Auswertungen. Mir kommt auch die SQL-Syntax, die Du benutzt etwas spanisch vor. In ABAP hat man etwas, was ziemlich einzigartig ist: die internen Tabelle mit mächtigen Befehlen wie z.B. COLLECT, welches den Group By Befehl von SQL ersetzt.

Du liest zum Beispiel mehrmals die gleichen Tabellen für unterschiedliche Kennzahlen. Leider kenne ich das Datenmodell von HR gar nicht und wir benutzen es hier auch nicht. Deshalb kann ich Dir nur ganz schematisch beschreiben, wie Du in eine interne Tabelle einliest und diese auswertest.

Deklaration der internen Tabelle:


types: begin of PA0001_typ.

            include structure PA0001.

types: end of PA0001_typ.

data:  itab_pa0001 type standard table of pa0001_typ,

         wa_pa0001 type pa0001_typ.  


start-of-selection.  "Starten des Reports


"In die interne Tabelle einlesen

select * from pa0001 appending corresponding fields of table itab_pa0001.


"Mitarbeiterzahl

describe table itab_pa0001 lines anzm.


"Sortieren nach Alter aufsteigend

sort itab_pa0002 by gbdat.
Du kannst Dir auch mit Join mehrere Tabellen zusammenlesen. Unten ein Beispiel von Modul EC-CS von mir aus meiner aktuellen Arbeit reinkopiert. Wichtig ist, daß du immer aliase benutzen mußt und Tilden zum Trennen zwischen Tabellennname und Feldname.
  select distinct a~item a~itcgy a~sign a~ituse b~txtsh b~txtmi

  from tf100 as a

    inner join tf101 as b on ( a~item = b~item and a~itclg = b~itclg )

      appending corresponding fields of table itab_tf101

  where

    a~itclg eq 'US'

    and

    b~langu eq 'EN'.
Wenn ein Join nicht geeignet ist, dann kannst Du auch in einer Schleife aus den verknüpften Tabelle querlesen mit SELECT SINGLE, was allerdings performancemäßig nicht optimal ist. Besser wäre es, die verknüpften Tabellen in interne Hashed-Tables einzulesen und dann mit READ TABLE querzulesen. Die Felder der internen Tabelle kannst Du frei definieren, also auch das Alter einfügen und dieses dann in einer Schleife füllen:
loop at itab_pa0002 into wa_pa0002.


   wa_pa0002-akt_alter = sy-datum - wa_pa0002-gbdat.

   modify wa_pa0002 from wa_pa0002


endloop.

Ich hoffe, das hilft Dir etwas weiter und verwirrt Dich nicht. Muß leider meine Kaffepause beenden.

Johannes

Link zu diesem Kommentar
Auf anderen Seiten teilen

danke für deine antwort, ich denke, damit kann ich was anfangen..wir werden sehen ;)

du hast recht, ich lese mehrmals die selben kennzahlen... aber mir wurde gesagt, dass ich das so machen muss.... ich werd aber nochmal nachfragen...

das problem ist halt, dass ich so gut wie keine ahnung von abap habe, weil ich gerade erst damit angefangen hab... aber wir werden sehen...

ich bin ja schon froh, dass ich die anderen aufgabenstellungen hinbekommen hab... :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

mein programm ist fast fertig.. und ich bin ganz stolz xD

aber ich hab noch folgendes problem:

ich muss aus einer internen tabelle den maximumwert auslesen, einmal von allen daten und einmal in abhängigkeit des anstellungsverhältnises..

leider geht das ja nicht mit

select max( feld )

ich hab jetzt die interne tabelle sortiert.. (nach dem alter der mitarbeiter),

aber wie lese ich den höchsten wert aus?

Link zu diesem Kommentar
Auf anderen Seiten teilen

ich muss aus einer internen tabelle den maximumwert auslesen, einmal von allen daten und einmal in abhängigkeit des anstellungsverhältnises..

leider geht das ja nicht mit

select max( feld )

ich hab jetzt die interne tabelle sortiert.. (nach dem alter der mitarbeiter),

aber wie lese ich den höchsten wert aus?

Respekt erst mal, daß du die internen Tabellen hinbekommen hast :)

SQL-Syntax kannst Du vergessen bei der Arbeit mit internen Tabellen.

Wenn du eine Tabelle mit Kopfzeile (das heißt in der Deklaration steht Occurs) hast, dann mußt du schreiben, um die erste Zeile aufzurufen:

read table itab index 1.

write: / itab-feld.
Ohne Kopfzeile mit expliziter Workarea:
read table itab into wa index 1.

write: / wa-feld.

Wenn Dir das mit der Kopfzeile und Workarea noch nicht soviel sagt, dann probier einfach beide Varianten, es wird bei der falschen eh ein fehler beim generieren ausgegeben.

Link zu diesem Kommentar
Auf anderen Seiten teilen

danke :)

das hat schonmal super geklappt... (ist eine tabelle ohne kopfzeile).

jetzt such ich schon seit einer weile nach einer möglichkeit eine where bedingung mit reinzubringen...

folgendes:

ich soll herausfinden, wie alt der älteste pensionist in der tabelle ist. das kann ich herausfiltern, da ein beschäftigungsstatus angegeben ist..

das bedeutet, ich suche nach alle beschäftigen, bei denen der beschäftigungsstatus '2' ist..

kann man das mit einbinden? und wenn ja, an welcher stelle? ich nehme an, dass muss ich direkt beim sortieren machen..damit nur die lines sortiert werden, in denen der beschäftigungsstatus "Pensionist" ist.. oder? leider habe ich noch nichts dazu gefunden...

Link zu diesem Kommentar
Auf anderen Seiten teilen

das hat schonmal super geklappt... (ist eine tabelle ohne kopfzeile).

jetzt such ich schon seit einer weile nach einer möglichkeit eine where bedingung mit reinzubringen...

Tabellen ohne Kopfzeile mit expliziter Workarea sind besser und flexibler. Das merkt man erst bei größeren Anwendungen (wo man etwa mehrere itabs von gleichen Typ hat und eine Workarea oder umgekehrt eine itab und mehrere worareas), aber man sollte sich von Anfang daran gewöhnen, nicht die primitiven alten Tabellen mit Kopf zu nehmen (wo die aktuelle Zeile genau heißt wie die ganze Tabelle, was unsauber werden kann).

Ersten Eintrag mit bestimmten Werten in einer (sortierten) Tabelle finden

read table itab into wa with key feld1 eq 'XYZ' feld2 eq 'ABC'.
Schleife über die Tabelle für nur bestimmte Werte:
loop at itab into wa where feld1 eq 'ABC'.

  write: / wa-feld2.

endloop.
Vielleicht machst Du ja eine interne Tabelle nur für die Pensionisten. Einfach im Deklarationsteil eine weitere itab deklarieren (eine Zeile Code) und in einer Schleife übergeben.
refresh itab_pensionisten.  "Alle Zeilen löschen

clear wa.                        "Die Workarea zurücksetzen

loop at itab into wa where pensioniert eq 'X'.

    append wa to itab_pensionisten.

endloop.
Link zu diesem Kommentar
Auf anderen Seiten teilen

*trommelwirbel* :D

ich bin fertig... :)

so viel arbeit.. für das hier :

Programm Z_AUSWERTUNG

Anzahl Mitarbeiter: 5.419

Anzahl aktiver Mitarbeiter: 5.383

Anzahl weiblicher Mitarbeiter: 2.291

Anzahl männlicher Mitarbeiter: 3.119

Alter des ältesten Mitarbeiters: 103

Alter des ältesten Pensionisten: 51

Durchschnittsalter der Mitarbeiter: 48

Anzahl Kinder insgesamt: 624

Anzahl Mitarbeiter mit Kind: 368

(nicht drüber wundern, dass weibliche + männliche Mitarbeiter nicht der Anzahl Mitarbeiter insgesamt entspricht..aber es gibt Mitarbeiter in der Liste, bei denen kein Geschlecht angegeben ist... )

nochmal Vielen Vielen Dank für eure Hilfe :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

zu früh gefreut...

neue aufgabe:

- beliebtester mitarbeitername?

- name des ältesten Mitarbeite & des ältesten Pensionisten?

neuer report:

- Wie viele Mitarbeiter wohnen in welchem Ort?

hier mal mein quelltext...

vielleicht habt ihr ideen oder tipps...

*&---------------------------------------------------------------------*

*& Report  Z_AUSWERTUNG

*&

*&---------------------------------------------------------------------*

*&

*& Report zum auswerten der logischen Datenbank PNPCE

*&---------------------------------------------------------------------*


REPORT  z_auswertung.



TABLES: pernr.

NODES peras.

INFOTYPES: 0001,

           0002,                                    "Daten zur Person

           0021,                                    "Familie/Bezugsperson

           0704.                                    "Information Familienangehörige

DATA: anzm TYPE i,                                  "Anzahl Mitarbeiter

      anzam TYPE i,                                 "Anzahl aktive Mitarbeiter

      anzwe TYPE i,                                 "Anzahl weibliche Mitarbeiter

      anzma TYPE i,                                 "Anzahl männliche Mitarbeiter

      maxa TYPE p,                                  "Alter des ältesten Mitarbeiters

      maxapen TYPE i,                               "Alter des ältesten Pensionisten

      dsm TYPE p DECIMALS 0,                        "Durchschnittsalter der Mitarbeiter

      anzk TYPE p,                                  "Anzahl Kinder insgesamt

      anzmk TYPE i,                                 "Anzahl Mitarbeiter mit Kind

      alter TYPE i,                                 "Alter des Mitarbeiters

      ages TYPE p,                                  "Feld, in dem alle Alter zusammegezählt werden

      gebda LIKE sy-datum,                          "Dem Feld ein Datumswert zuweisen

      ls_p0002 TYPE pa0002,

      ls_p0002_a TYPE zp0002_alter,

      lt_p0002_a TYPE TABLE OF zp0002_alter,

      wa LIKE ls_p0002_a,

      ls_p0001 TYPE pa0002,

      ls_p0001_a TYPE zp0001_alter,

      lt_p0001_a TYPE TABLE OF zp0001_alter,

      wa2 LIKE ls_p0001_a,

      name TYPE c,

      kinder TYPE p.                                 "Anzahl der Kinder, pro Mitarbeiter





SELECT COUNT( DISTINCT pernr )                        "Anzahl Mitarbeiter

  INTO anzm

   FROM pa0002.



SELECT COUNT( DISTINCT pernr )                         "Anzahl aktiver Mitarbeiter

  INTO anzam

  FROM pa0001

  WHERE persg = 1.



SELECT COUNT( DISTINCT pernr )                         "Anzahl weiblicher Mitarbeiter

INTO anzwe

FROM pa0002

WHERE gesch = 2.


* Anzahl männliche Mitarbeiter


SELECT COUNT( DISTINCT pernr )

 INTO anzma

 FROM pa0002

 WHERE gesch = 1.


* Anzahl der Mitarbeiter mit Kinder


SELECT COUNT( DISTINCT pernr )

INTO anzmk

FROM pa0002

WHERE anzkd >= 1.




* Alter der Mitarbeiter zusammenzählen


SELECT gbdat FROM pa0002

  INTO gebda.

  alter = sy-datum - gebda.

  DIVIDE alter BY 365.

  ages = ages + alter.

ENDSELECT.



* Berechnung des Durchschnittsalters


dsm = ages / anzm.



* Anzahl der Kinder zusammenzählen


SELECT anzkd FROM pa0002

  INTO kinder

  WHERE anzkd >= 1.

  anzk = anzk + kinder.

ENDSELECT.






* Alter des ältesten Mitarbeiters


CLEAR: ages.

SELECT *

  INTO ls_p0002

  FROM pa0002.


  MOVE-CORRESPONDING ls_p0002 TO ls_p0002_a.

  alter = sy-datum - ls_p0002_a-gbdat.

  DIVIDE alter BY 365.


  ls_p0002_a-alter = alter.


  APPEND ls_p0002_a TO lt_p0002_a.



ENDSELECT.


DO 1 TIMES.

  SORT lt_p0002_a DESCENDING BY alter.


  READ TABLE lt_p0002_a INTO wa INDEX 1.

  IF sy-subrc <> 0.

    EXIT.

  ENDIF.


ENDDO.


* Alter des ältesten Pensionisten


CLEAR: ages.

SELECT *

  INTO ls_p0001

  FROM pa0002.


  MOVE-CORRESPONDING ls_p0001 TO ls_p0001_a.

  alter = sy-datum - ls_p0002_a-gbdat.

  DIVIDE alter BY 365.


  ls_p0001_a-alter = alter.


  APPEND ls_p0001_a TO lt_p0001_a.

ENDSELECT.


DO 1 TIMES.

  READ TABLE lt_p0001_a INTO wa2 WITH KEY persg = '2'.


  SORT lt_p0001_a DESCENDING BY alter.



  READ TABLE lt_p0001_a INTO wa2 INDEX 1.

  IF sy-subrc <> 0.

    EXIT.

  ENDIF.


ENDDO.





* Ausgabe der Ergebnisse


WRITE: / 'Anzahl Mitarbeiter:', anzm,

       / 'Anzahl aktiver Mitarbeiter:', anzam,

       / 'Anzahl weiblicher Mitarbeiter:', anzwe,

       / 'Anzahl männlicher Mitarbeiter:', anzma,

       / 'Alter des ältesten Mitarbeiters:', wa-alter,

       / 'Alter des ältesten Pensionisten:', wa2-alter,

       / 'Durchschnittsalter der Mitarbeiter:', dsm,

       / 'Anzahl Kinder insgesamt:', anzk,

       / 'Anzahl Mitarbeiter mit Kind:', anzmk.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 3 Wochen später...

Offen für Verbesserungsvorschläge/konstruktive Kritik bin ich immer.. sonst würd ich hier nicht nachfragen :)

Leider kann ich im Moment (wegen Updates) nicht auf mein Programm zugreifen.. werde den Quellcode dann am Dienstag posten.. (Montag ist in Bayern Feiertag:P)

Schönes Wochenende :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

hier der fertige Quellcode:




TABLES: pernr.

NODES peras.

INFOTYPES: 0001,

           0002,                                    "Daten zur Person

           0021,                                    "Familie/Bezugsperson

           0704.                                    "Information Familienangehörige

DATA: anzm TYPE i,                                  "Anzahl Mitarbeiter

      anzam TYPE i,                                 "Anzahl aktive Mitarbeiter

      anzwe TYPE i,                                 "Anzahl weibliche Mitarbeiter

      anzma TYPE i,                                 "Anzahl männliche Mitarbeiter

      maxa TYPE p,                                  "Alter des ältesten Mitarbeiters

      maxapen TYPE i,                               "Alter des ältesten Pensionisten

      dsm TYPE p DECIMALS 0,                        "Durchschnittsalter der Mitarbeiter

      anzk TYPE p,                                  "Anzahl Kinder insgesamt

      anzmk TYPE i,                                 "Anzahl Mitarbeiter mit Kind

      alter TYPE i,                                 "Alter des Mitarbeiters

      ages TYPE p,                                  "Feld, in dem alle Alter zusammegezählt werden

      gebda LIKE sy-datum,                          "Dem Feld ein Datumswert zuweisen

      ls_p0002 TYPE pa0002,

      ls_p0002_a TYPE zp0002_alter,

      lt_p0002_a TYPE TABLE OF zp0002_alter,

      wa LIKE ls_p0002_a,

      ls_p0001 TYPE pa0001,

      ls_p0001_a TYPE zp0001_alter,

      lt_p0001_a TYPE TABLE OF zp0001_alter,

      ls_oz TYPE zort_zaehler,

      lt_oz TYPE TABLE OF zort_zaehler,

      ls_oz_n TYPE zort_zaehler,

      lt_oz_n TYPE TABLE OF zort_zaehler,

      oz LIKE ls_oz,

      wa2 LIKE ls_p0001_a,

      wa4 LIKE ls_p0002_a,

      name TYPE string,

      name2 TYPE string,

      ls_pensionisten TYPE zpensionisten,

      lt_pensionisten TYPE TABLE OF zpensionisten,

      wa3 LIKE ls_pensionisten,

      pens LIKE ls_pensionisten,

      kinder TYPE p.                                 "Anzahl der Kinder, pro Mitarbeiter




* Anzahl Mitarbeiter


SELECT COUNT( DISTINCT pernr )

  INTO anzm

   FROM pa0002.


* Anzahl aktiver Mitarbeiter


SELECT COUNT( DISTINCT pernr )

  INTO anzam

  FROM pa0001

  WHERE persg = 1.


* Anzahl weiblicher Mitarbeiter


SELECT COUNT( DISTINCT pernr )

INTO anzwe

FROM pa0002

WHERE gesch = 2.


* Anzahl männliche Mitarbeiter


SELECT COUNT( DISTINCT pernr )

 INTO anzma

 FROM pa0002

 WHERE gesch = 1.


* Anzahl der Mitarbeiter mit Kinder


SELECT COUNT( DISTINCT pernr )

INTO anzmk

FROM pa0002

WHERE anzkd >= 1.




* Alter der Mitarbeiter zusammenzählen


SELECT gbdat FROM pa0002

  INTO gebda.

  alter = sy-datum - gebda.

  DIVIDE alter BY 365.

  ages = ages + alter.

ENDSELECT.



* Berechnung des Durchschnittsalters


dsm = ages / anzm.



* Anzahl der Kinder zusammenzählen


SELECT anzkd FROM pa0002

  INTO kinder

  WHERE anzkd >= 1.

  anzk = anzk + kinder.

ENDSELECT.




* Alter des ältesten Mitarbeiters


CLEAR: ages.

SELECT *

  INTO ls_p0002

  FROM pa0002.


  MOVE-CORRESPONDING ls_p0002 TO ls_p0002_a.

  alter = sy-datum - ls_p0002_a-gbdat.

  DIVIDE alter BY 365.


  ls_p0002_a-alter = alter.


  APPEND ls_p0002_a TO lt_p0002_a.



ENDSELECT.


DO 1 TIMES.

  SORT lt_p0002_a DESCENDING BY alter.


  READ TABLE lt_p0002_a INTO wa INDEX 1.

  IF sy-subrc <> 0.

    EXIT.

  ENDIF.


ENDDO.


* Ausgabe der Ergebnisse


CONCATENATE wa-vorna wa-nachn INTO name SEPARATED BY space.



WRITE: / 'Anzahl Mitarbeiter:', anzm,

       / 'Anzahl aktiver Mitarbeiter:', anzam,

       / 'Anzahl weiblicher Mitarbeiter:', anzwe,

       / 'Anzahl männlicher Mitarbeiter:', anzma,

       / 'Alter des ältesten Mitarbeiters:', wa-alter,

       / 'Durchschnittsalter der Mitarbeiter:', dsm,

       / 'Anzahl Kinder insgesamt:', anzk,

       / 'Anzahl Mitarbeiter mit Kind:', anzmk.



CLEAR: ls_p0001, ls_p0001_a, lt_p0001_a, ls_p0002, ls_p0002_a, lt_p0002_a.


* Auslesen von pa0001 in ls_p0001


SELECT *

  INTO ls_p0001

  FROM pa0001.


  MOVE-CORRESPONDING ls_p0001 TO ls_p0001_a.


  APPEND ls_p0001_a TO lt_p0001_a.

ENDSELECT.



* Berechnung des Alters


SELECT *

  INTO ls_p0002

  FROM pa0002.


  MOVE-CORRESPONDING ls_p0002 TO ls_p0002_a.

  alter = sy-datum - ls_p0002_a-gbdat.

  DIVIDE alter BY 365.


  ls_p0002_a-alter = alter.


  APPEND ls_p0002_a TO lt_p0002_a.

ENDSELECT.




* Erstellen einer Tabelle für Pensionisten


LOOP AT lt_p0002_a INTO wa.

  READ TABLE lt_p0001_a INTO wa2 WITH KEY persg = '2'.


  pens-alter = sy-datum - ls_p0002_a-gbdat.

  DIVIDE pens-alter BY 365.


*  ls_p0002_a-alter = pens-alter.



  IF wa-pernr EQ wa2-pernr.

    MOVE-CORRESPONDING wa TO ls_pensionisten.

    MOVE-CORRESPONDING wa2 TO ls_pensionisten.

    APPEND ls_pensionisten TO lt_pensionisten.

  ENDIF.



ENDLOOP.



SORT lt_pensionisten DESCENDING BY alter.

READ TABLE lt_pensionisten INTO pens INDEX 1.


pens-alter = sy-datum - pens-gbdat.

divide pens-alter by 365.


ls_pensionisten-alter = pens-alter.



CONCATENATE pens-vorna pens-nachn INTO name2 SEPARATED BY space.



* Geburtsorte und Anzahl, der dort geborenen Mitarbeiter, auslesen


* READ TABLE lt_p0002_a INTO wa INDEX 1.


LOOP AT lt_p0002_a INTO wa4.

  READ TABLE lt_oz INTO oz WITH KEY gebort = wa4-gbort.


  IF sy-subrc <> 0.

    oz-zaehler = oz-zaehler + 1.

    oz-gebort = wa4-gbort.

    APPEND oz TO lt_oz.


  ELSE.

    oz-zaehler = oz-zaehler + 1.

    MODIFY lt_oz FROM oz TRANSPORTING zaehler WHERE gebort = oz-gebort.

  ENDIF.

ENDLOOP.


LOOP AT lt_oz INTO oz.

  WRITE: / 'Geburtsort:', oz-gebort, 'Anzahl Mitarbeiter:', oz-zaehler DECIMALS 0.

ENDLOOP.


* Ausgabe


WRITE: / 'Name des ältesten Mitarbeiters:', name,

       / 'Alter des ältesten Pensionisten:', pens-alter,

       / 'Name des ältesten Pensionisten:', name2.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mal ein paar Dinge zu deinem Machwerk (einiges wurde von den Kollegen schon angemerkt im Verlauf):

- Performance:

Die Art und Weise wie du selektierst funktioniert zwar, birgt aber großes Verbesserungspotential in punkto Performance und ressourcensparendem Ablauf:

Du hast z.B. jede Menge einzelne Selects auf die pa0002, mit jedem Select suchst du dir einen bestimmten Wert heraus. Nachteil dabei: Hohe Anzahl DB-Abfragen, hoher Traffic, hohe Kosten.

Bessere Lösung: Mit einer einzigen Abfrage holst du alle relevanten Daten aus der pa0002 in eine itab_pa0002, anschließend kannst du über die itab loopen und in aller Ruhe deine Berechnungen durchführen. Eventuell auch einen Join auf pa0001 und pa0002, spart auch wieder einiges.

Bei internen Tabellen stets mit itab und Arbeitsbereich arbeiten, nicht mit den Kopfzeilen... spätestens wenn du das erste Mal 2 Stunden Fehlersuche betrieben hast und dann merkst, daß in der Kopfzeile noch Daten sind die anderswo für Fehlfunktionen sorgen, hälst du dich daran :)

- Struktur / Aufbau deines Reports:

Du liest erst die eine Hälfte der Daten, gibst diese dann aus; anschließend wird nochmal was anderes gelesen und danach die neuen Ergebnisse ausgegeben. Funktioniert, ist aber nicht sonderlich "schön". Generell sollte man zuerst die Erhebung / Verarbeitung der Daten und zum Schluß die Ausgabe anstreben.

- Übersichtlichkeit:

Auch wenn dein Report noch nicht umfangreich ist, solltest du nach Möglichkeit einzelne Arbeitsschritte in Formroutinen auslagern. Das macht das ganze sehr viel übersichtlicher, gerade wenn du umfangreiche Reports entwickelst, wird das relevant.

Gewöhne dir eine einheitliche Namensgebung an, z.B. lt_mara ist eine LokaleTabelle der DB-Tabelle MARA und ls_mara ist die zugehörige LokaleStruktur, also dein Arbeitsbereich. Das geht dann noch weiter, z.B. p_name wäre ein Parameter für den Namen, lv_count wäre eine LokaleVariable eines Zählers.

- Fehlerhandling:

Last but not least :) Aktuell hast du sogut wie keine Fehlerbehandlung... was geschieht, wenn einer der Selects nicht erfolgreich ist? Die darauf aufbauenden Berechnungen gehen auf die Bretter! Was passiert wenn eine der Berechnungen schiefgeht? Im besten Falle gibt es eine Null als Ergebnis, im schlimmsten Fall gibts einen Kurzdump z.B. wegen Division_by_Zero o.ä., was du nicht abfängst.

Das klingt jetzt vielleicht etwas entmutigend, aber soll keinesfalls so rüberkommen... jeder hat mal ungefähr so angefangen :)

Viel Erfolg...

Alex

Link zu diesem Kommentar
Auf anderen Seiten teilen

erstmal danke für deine antwort.. :) aber dazu möcht ich kurz noch was anmerken :D

Mal ein paar Dinge zu deinem Machwerk (einiges wurde von den Kollegen schon angemerkt im Verlauf):

- Performance:

mir ist klar, dass die performance nicht so toll ist, wenn man das auf größere tabellen etc. umsetzten will... ist aber im moment genau so gewollt (meine ausbildungsbeauftragte...[ja..so heißt das hier ;)] wollte genau deshalb, dass ich das so löse.. um zu sehen, dass die performance schlecht ist... sie meinte wir wollten uns erstmal um das problem selber kümmern..die performance kommt erst später drann... erstmal ist syntax lernen angesagt :D

natürlich hast du recht.. dass das nicht so der hit ist :)

die strukturierung ist so gelaufen, weil ich zu unterschiedlichen zeitpunketen aufgaben bekommen habe... um zu sehen, wann was war... (auch von meinem abb so gewünscht)

mit dem fehlerhandling ist es das selbe wie mit der performance... (habe mittlerweile auch schon kleinere programme mit fehlerhandling geschrieben...)

wir ich schon gesagt hab, bin ich sehr offen für konstruktive kritik.. mir ist klar, dass ich mir in den nächsten drei jahren noch sehr oft sowas in der art anhören muss.. aber ich bin ja schließlich hier ums zu lernen ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...