neinal Geschrieben 30. September 2010 Geschrieben 30. September 2010 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. Zitieren
neinal Geschrieben 30. September 2010 Autor Geschrieben 30. September 2010 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... Zitieren
neinal Geschrieben 30. September 2010 Autor Geschrieben 30. September 2010 update: der syntax-fehler mit der tabelle besteht immer noch.. aber ich hab ne neue frage... (ja.. ich bin schlimm ^^) wie kann ich anhand eines geburtsdatums berechnen, wie alt eine person ist? Zitieren
ronaldus Geschrieben 30. September 2010 Geschrieben 30. September 2010 siehe in SQL korrektes Alter berechnen mfg ron Zitieren
neinal Geschrieben 1. Oktober 2010 Autor Geschrieben 1. Oktober 2010 siehe in SQL korrektes Alter berechnen mfg ron danke für deine schnell antwort.. habs aber gestern kurz vor feierabend dann doch noch selber hinbekommen Zitieren
neinal Geschrieben 1. Oktober 2010 Autor Geschrieben 1. Oktober 2010 (bearbeitet) 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 1. Oktober 2010 von neinal Zitieren
ronaldus Geschrieben 4. Oktober 2010 Geschrieben 4. Oktober 2010 Hi, vielleicht kannst Du die Berechnungsfunktion des Alters für alter einsetzen... SELECT MAX(DATDIFF(NOW(), p.Geburtsdatum))/365 ).... mfg ron Zitieren
Wurmi Geschrieben 5. Oktober 2010 Geschrieben 5. Oktober 2010 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. Zitieren
michaelmeier Geschrieben 7. Oktober 2010 Geschrieben 7. Oktober 2010 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> 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 Zitieren
AlexS1980 Geschrieben 7. Oktober 2010 Geschrieben 7. Oktober 2010 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 Zitieren
neinal Geschrieben 11. Oktober 2010 Autor Geschrieben 11. Oktober 2010 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. Zitieren
Wurmi Geschrieben 11. Oktober 2010 Geschrieben 11. Oktober 2010 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 Zitieren
neinal Geschrieben 11. Oktober 2010 Autor Geschrieben 11. Oktober 2010 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... Zitieren
neinal Geschrieben 12. Oktober 2010 Autor Geschrieben 12. Oktober 2010 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? Zitieren
Wurmi Geschrieben 12. Oktober 2010 Geschrieben 12. Oktober 2010 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. Zitieren
neinal Geschrieben 12. Oktober 2010 Autor Geschrieben 12. Oktober 2010 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... Zitieren
Wurmi Geschrieben 12. Oktober 2010 Geschrieben 12. Oktober 2010 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. Zitieren
neinal Geschrieben 12. Oktober 2010 Autor Geschrieben 12. Oktober 2010 *trommelwirbel* 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 Zitieren
neinal Geschrieben 12. Oktober 2010 Autor Geschrieben 12. Oktober 2010 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. Zitieren
neinal Geschrieben 29. Oktober 2010 Autor Geschrieben 29. Oktober 2010 Hallo Ihr, mein Programm funktioniert jetzt schon seit längerem. Besteht Interesse am Quellcode? Zitieren
AlexS1980 Geschrieben 29. Oktober 2010 Geschrieben 29. Oktober 2010 Zeig halt mal her, evtl. kann man noch den ein oder anderen Tip loswerden, falls du offen für Verbesserungsvorschläge bist... Zitieren
neinal Geschrieben 29. Oktober 2010 Autor Geschrieben 29. Oktober 2010 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 Zitieren
neinal Geschrieben 2. November 2010 Autor Geschrieben 2. November 2010 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. Zitieren
AlexS1980 Geschrieben 2. November 2010 Geschrieben 2. November 2010 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 Zitieren
neinal Geschrieben 4. November 2010 Autor Geschrieben 4. November 2010 erstmal danke für deine antwort.. aber dazu möcht ich kurz noch was anmerken 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 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 Zitieren
Empfohlene Beiträge
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.