[gelöst] Daten in einer Tabelle ändern

16. Juli 2009 10:51

Hallo

ich habe da folgendes Problem und ich komme nicht weiter.

Das Problem:
ich habe eine Tabelle in der ich daten über mitarbeiter habe, da stehen arbeitszeit = 30 Arbeitseinheiten und darunter stehen die namen der Mitarbeiter.

die tabelle hat folgenden aufbau:

belegnr. datum beschreibung arbeitseinheiten
1 0106 arbeitseinheit 30
1 0106 mitarbeiter1 0
2 0206 arbeitseinheit 50
2 0206 mitarbeiter2 0
2 0206 mitarbeiter3 0

so sieht in etwa die tabelle aus. ich möchte jetzt in einem report die tabelle ausgeben mit den mitarbeitern und den arbeitseinheiten dazu.
Mein Problem ist nur wie kann ich den mitarbeiten die arbeitseinheiten zuweisen?
bei belegnr 2 muss die arbeitseinheit durch die beiden mitarbeiter geteilt werden

ich mache gerade folgendes:
ich gehe in dem report die tabelle durch und speicher die namen in einer anderen tabelle zuordnung über die belegnummer, zähle mit einer variable die aw pro beleg zB. beleg 1 30 arbeitseinheit usw. und ich zähle die anzahl der namen der mitarbeiter mit einer variable. so das funktioniert ja auch wie bekomme ich aber nun die daten der arbeitseiheiten in meine neue tabelle wo die namen sind.

ich hoffe mir kann jemand helfen, siehste da jetzt schon mehre tage dran und bin schon am verzweifeln

MFG Susann
Zuletzt geändert von flowerdog am 30. Juli 2009 10:53, insgesamt 5-mal geändert.

Re: Daten in einer Tabelle ändern

16. Juli 2009 11:07

Wenn ich das alles richtig verstehe, könnte es so gehen:
Du gehst über alle Datensätze, in denen nur Arbeitseinheiten drin stehen. Für jeden suchst du die passenden Datensätze mit den Mitarbeitern. Anhand der Anzahl an MA-Datensätzen weißt du, wieviele AE jeder bekommen muss, und diesen Wert kannst du den Datensätzen auch gleich zuordnen.

Re: Daten in einer Tabelle ändern

16. Juli 2009 11:33

ja die idee hatte ich auch schon funktioniert aber nicht.

ich laufe im report die eine tabelle durch, speiche beim durchlaufen die wichtigen daten bzw. die namen in eine neue tabelle. den zähle ich die arbeitseinheiten und speichere diese in einer tempöräen tabelle ab.

Report sieht so aus:

DataItem Name
Sales Invoice Header <Sales Invoice Header> -----> das ist der start entsprechende Filter setzen und so weiter
Sales Invoice Line <Sales Invoice Line> ----> dann wird die durchlaufen und auch und auch ausgeben und die sachen die ich brauche gespeichert
Test SU <Test SU> ----> dann kommt die Tabelle wo die namen drin stehn und diese wird hier extra nochmal ausgeben hier fehlen
----> nur noch arbeitseinheiten
an welche stelle muss ich jetzt die arbeitseinheiten zuweisen ???

Re: Daten in einer Tabelle ändern

16. Juli 2009 12:07

Wenn ich es auch richtig verstanden habe würde ich wie folgt den Report erstellen:
(Eigentlich fehlt nur ein weiter Durchlauf zum zuweisen der Stunden)

a. Vorverarbeitung der Daten (ohne DataItem, sondern in einer Funktion mit einer neuen Record Variable!)
-->Sprich: Kummulieren der Werte je Beleg und in einer TmpTabelle speichern (Wenn vorhanden MODIFY, wenn nicht INSERT)
(Diese müsste zwei Durchläufe machen, 1. Erfassen der Mitarbeiter, 2. Verteilen der Arbeitsstunden)
b. Ausgabe der Daten über zwei Integer Dataitems:
-->Das erste Filtert** holt mit FIND die Datensätze aus der TmpTabelle, wenn keiner mehr da, dann CurrReport.SKIP.
-->Auf dem Zweiten (MaxIteration = 1) (Dieses dient nur der Schleifenverabeitung)

**Das erste Dataitem auf OnPredataItem auf die Anzahl Datensätze Filtern wie in der TmpTabelle vorgefunden.

***************************
Nach dem ich das geschrieben habe fällt mir auf, das es eigentlich reichen würde, wenn du auf OnPredataItem - TestSU eine weitere Verarbeitung (mit Schleife) einfügst und hier die Arbeitsstunden verteilst!

Re: Daten in einer Tabelle ändern

16. Juli 2009 12:45

hi

danke klappt schonmal so weit aber jetzt habe ich folgende sache:


Test SU - OnPreDataItem()
//"Test SU".SETRANGE("Test SU".datum,"Sales Invoice Header"."Order Date");
IF "Test SU".FINDFIRST THEN BEGIN
TempRec.SETRANGE(TempRec."Document No.", "Test SU".belegnr);
IF TempRec.FINDFIRST THEN BEGIN
REPEAT
"Test SU".menge := TempRec.Quantity;
"Test SU".MODIFY;
UNTIL TempRec.NEXT = 0;
END;
END;

das ist der quelltext den ich jetzt beim durchlaufen der testdatenbank nutze
nur funktioniert das nur für den ersten namen und nicht für alle
was fehlt jetzt schon noch???

Re: Daten in einer Tabelle ändern

16. Juli 2009 12:48

blöde frage hat nur repeat until schleife gefehlt

Danke schön es funktioniert :-D

Re: [Gelöst] Daten in einer Tabelle ändern

16. Juli 2009 13:57

Hallo flowerdog,

dein Quelltext ist leichter zu lesen und zu verstehen, wenn du ihn zwischen so genannte Code-Tags setzt. Insbesondere deine Formatierungen werden so auch beibehalten.

Daher bitten wir dich, vor und nach deinem Quelltext diese Code-Tags einzufügen. Beispiel:
[code]Dein Quelltext[/code]


Gruß, Mikka
MSDynamics.de-Team
Zuletzt geändert von Natalie am 16. Juli 2009 15:00, insgesamt 2-mal geändert.
Grund: [gelöst] ist schon gesetzt worden

Re: [Gelöst] Daten in einer Tabelle ändern

16. Juli 2009 14:06

Kleiner Tipp:
Mir ist in Deinem Code aufgefallen, das du FINDFIRST und danach eine REPEAT ... UNTIL Schleife benuntzt.
Dieses ist sehr un-Performand (auf einem SQL-Server), besser ist es ein FINDSET zu nutzen :-)
(FINDFIRST / FINDLAST immer nur wenn der erste oder letzte DS ohne Schleife benötigt wird!)

Wenn zunächst noch geprüft werden soll ob überhaupt ein DS vorhanden ist, nutze: NOT ISEMPTY
(Ist wesentlich schneller und kostet weniger Ressoucen!)

Z.B:
Code:
"Test SU".SETRANGE(irgend ein Filter, oder auch nicht!);
IF NOT "Test SU".ISEMPTY THEN BEGIN
  TempRec.SETRANGE(TempRec."Document No.", "Test SU".belegnr);

  IF TempRec.FINDSET THEN BEGIN
    REPEAT
      "Test SU".menge := TempRec.Quantity;
      "Test SU".MODIFY;
    UNTIL TempRec.NEXT = 0;
  END;
END;

Re: [Gelöst] Daten in einer Tabelle ändern

16. Juli 2009 14:13

Hm, der Quelltext wird so nichts brauchbares liefern, da Record "Test SU" zwar gefiltert, aber die Suche nicht ausgeführt wird ;-)
Auch ist es nicht nötig, die Variable so oft auf MODIFY zu setzen.
Sollte nicht außerdem TempRec.Quantity als Summe in "Test SU".Menge einfließen? Sonst würde das REPEAT-UNTIL-Konstrukt doch gar keinen Sinn machen ...

Daher mein Gegenvorschlag

Code:
"Test SU".SETRANGE(irgend ein Filter, oder auch nicht!);
IF "Test SU".FINDFIRST THEN BEGIN // <---- wichtig
  TempRec.SETRANGE(TempRec."Document No.", "Test SU".belegnr);

  IF TempRec.FINDSET THEN BEGIN
    REPEAT
      "Test SU".menge += TempRec.Quantity; // aufaddieren, nicht gleichsetzen
    UNTIL TempRec.NEXT = 0;
    Test SU".MODIFY;
  END;
END;

Re: [Gelöst] Daten in einer Tabelle ändern

16. Juli 2009 14:15

mikka hat geschrieben:Dieses ist sehr un-Performand (auf einem SQL-Server), besser ist es ein FINDSET zu nutzen

Das sagt man, aber ich hab´s mal gemessen, und da war bei einigen hundert Datensätzen kein Unterschied zwischen findset und findfirst :-?

Re: [Gelöst] Daten in einer Tabelle ändern

16. Juli 2009 14:20

McClane hat geschrieben:
mikka hat geschrieben:Dieses ist sehr un-Performand (auf einem SQL-Server), besser ist es ein FINDSET zu nutzen

Das sagt man, aber ich hab´s mal gemessen, und da war bei einigen hundert Datensätzen kein Unterschied zwischen findset und findfirst :-?


Hm, kann es sein, dass deine Datenmenge bei <= 500 Datensätzen war? 500 ist ja die typische Datensatzmenge (voreingestellt unter Datenbank -> Ändern), die "mit einem Haps" gelesen werden kann. Vielleicht hättest du bei einer Menge deutlich größer als 500 mehr Unterschied gemessen...
Wild geraten, stryk wird wahrscheinlich entsetzt mit den Augen rollen :oops:

Re: [Gelöst] Daten in einer Tabelle ändern

16. Juli 2009 14:25

Natalie hat geschrieben:Hm, kann es sein, dass deine Datenmenge bei <= 500 Datensätzen war? 500 ist ja die typische Datensatzmenge (voreingestellt unter Datenbank -> Ändern), die "mit einem Haps" gelesen werden kann. Vielleicht hättest du bei einer Menge deutlich größer als 500 mehr Unterschied gemessen...
Wild geraten, stryk wird wahrscheinlich entsetzt mit den Augen rollen

War auch meine Vermutung, aber daran lag es nicht (je nach Filter waren es mehr als 10000 Datensätze, Laufzeit des Reports waren viele Minuten bis einige Stunden). Ich dachte ja schon ganz froh, dass ich die Bremse in dem Report gefunden hätte, aber das Ersetzen der findfirsts durch findset hat - abgesehen von der Verständlichkeit des Codes - absolut nichts gebracht. Nicht eine Sekunde.

Re: [Gelöst] Daten in einer Tabelle ändern

16. Juli 2009 14:58

ich brauche nochmal eure Hilfe ich will den daten von der Testtabelle nochmal zusammen fassen und zwar wenn gleiches Datum und gleiche beschreibung den soll in eine temporäre tabelle der name datum und menge gespeichert werden okay soweit auch okay.

das ist folgender quelltext:



IF (testrec.datum <> "Test SU".datum) AND (testRec2.beschreibung <>"Test SU".beschreibung) THEN BEGIN
testRec2.zeilennr := "Test SU".zeilennr;
testRec2.datum := "Test SU".datum;
testRec2.beschreibung := "Test SU".beschreibung;
testRec2.menge := "Test SU".menge;
testRec2.einheit := "Test SU".einheit;
testRec2.INSERT;
END
ELSE BEGIN
testRec2.menge += "Test SU".menge;
testRec2.MODIFY;
END;
UNTIL "Test SU".NEXT = 0;

den habe ich im body beim test su tabellen durchlauf in onpostsections rein geschreiben will ich dachte der könnte er hin.

funktioniert nur nicht. es kommt der fehler das in der Test su tabelle die zeilennr. 1 nicht existiert. Wer weiß was ich falsch mache?!?

Re: Daten in einer Tabelle ändern

16. Juli 2009 14:59

Bitte beachte mikkas obigen Beitrag und editiere deine Beiträge.

Re: Daten in einer Tabelle ändern

16. Juli 2009 15:02

okay nochmal hier der Quelltext

Code:
    IF (testRec2.datum <> "Test SU".datum) AND (testRec2.beschreibung <>"Test SU".beschreibung) THEN BEGIN
      testRec2.zeilennr := "Test SU".zeilennr;
      testRec2.datum := "Test SU".datum;
      testRec2.beschreibung := "Test SU".beschreibung;
      testRec2.menge := "Test SU".menge;
      testRec2.einheit := "Test SU".einheit;
      testRec2.INSERT;
    END
    ELSE BEGIN
      testRec2.menge += "Test SU".menge;
      testRec2.MODIFY;
    END;
Zuletzt geändert von flowerdog am 16. Juli 2009 15:17, insgesamt 1-mal geändert.

Re: Daten in einer Tabelle ändern

16. Juli 2009 15:07

Kennst du den Unterschied zwischen Beiträge editieren und neu schreiben? ;-)

Also, bevor du ein testRec2.MODIFY; ausführst, musst du testRec2 zuvor geholt/geladen haben.
Ich sehe in deinem Quelltext aber nirgends ein testRec2.GET oder testRec2.FIND. Außerdem verwendest du zwei Variablen: testrec und testrec2 - welche soll worauf referenzieren?
Kann es sein, dass du nicht alles an Quelltext hierhin kopiert hast?

Re: Daten in einer Tabelle ändern

16. Juli 2009 15:13

Natalie hat geschrieben:Kennst du den Unterschied zwischen Beiträge editieren und neu schreiben? ;-)

Ja kenn ich. :-)
klappt beim nächsten Mal bestimmt auch. bin nur gerade etwas gestresst.
jupps das mit dem testrec war ein versehen, muss natürlich auch testRec2 sein. das ist schon der ganze quelltext reicht doch vom prinzip. das mit dem testrec2.find fehlt wirklich das muss noch rein.

aber ob das schon reicht???

Re: Daten in einer Tabelle ändern

16. Juli 2009 15:22

flowerdog hat geschrieben:aber ob das schon reicht???

Schreib deinen ganzen Quelltext rein und wir schauen mal ;-)

Re: Daten in einer Tabelle ändern

16. Juli 2009 15:26

das ist der ganze Quelltext

Test SU, Body (1) - OnPostSection()
Code:
testRec2.FIND;
     IF (testRec2.datum <> "Test SU".datum) AND (testRec2.beschreibung <>"Test SU".beschreibung) THEN BEGIN
      testRec2.zeilennr := "Test SU".zeilennr;
      testRec2.datum := "Test SU".datum;
      testRec2.beschreibung := "Test SU".beschreibung;
      testRec2.menge := "Test SU".menge;
      testRec2.einheit := "Test SU".einheit;
      testRec2.INSERT;
    END
    ELSE BEGIN
      testRec2.menge += "Test SU".menge;
      testRec2.MODIFY;
    END;

Re: Daten in einer Tabelle ändern

16. Juli 2009 15:30

Ich schreib meine Bemerkungen direkt in die Quelltextzeilen:

Code:
testRec2.FIND; // Keine Filterung? Kein REPEAT? Und keine Absicherung -> Wenn testRec2 leer sein sollte, gibts einen Laufzeitfehler.
     IF (testRec2.datum <> "Test SU".datum) AND (testRec2.beschreibung <>"Test SU".beschreibung) THEN BEGIN
// Vorsicht - womit ist "Test SU" gefüllt? Wo wurde es gefüllt?
      testRec2.zeilennr := "Test SU".zeilennr;
      testRec2.datum := "Test SU".datum;
      testRec2.beschreibung := "Test SU".beschreibung;
      testRec2.menge := "Test SU".menge;
      testRec2.einheit := "Test SU".einheit;
      testRec2.INSERT; // Was ist der Primärschlüssel von testRec2? Stellst du sicher, dass du keinen Datensatz einfügst, den es schon gibt?
    END
    ELSE BEGIN
      testRec2.menge += "Test SU".menge;
      testRec2.MODIFY;
    END;

Re: [Gelöst] Daten in einer Tabelle ändern

16. Juli 2009 15:34

McClane hat geschrieben:
mikka hat geschrieben:Dieses ist sehr un-Performand (auf einem SQL-Server), besser ist es ein FINDSET zu nutzen

Das sagt man, aber ich hab´s mal gemessen, und da war bei einigen hundert Datensätzen kein Unterschied zwischen findset und findfirst :-?


Das kann je noch Umstand auch zutreffen. Deswegen soll ja auch ein FIND('-') nicht "Blind" ersetzt werden gegen ein FINDSET, sondern gegen ein FINDFIRST bzw. ISEMPTY / NOT ISEMPTY.
U.U. ist ein FINDSET geeigneter, wenn nur der erste DS benötigt wird.

Hier ein paar Beispiele mit Wert die getestet habe mit diesen Befehlen (alle Werte in ms):
Code:
// Alle mit nachfolgender REPEAT .. UNTIL Schleife!
// Zufriff auf Kreditorposten mit diversen Filtern
//Anzahl Datensätze im Filter 9926

Test 1.: Ohne geeigneten KEY (Key.: Lfd.)
FIND('-')  FINDSET    FINDFIRST
4015       2556       3844
3688       2672       3718
4094       2687       4031
4437       2656       3797

Test 2.: Mit (teils) geeignetem Key (Nicht alle gefilterten Felder sind im Key enthalten)
FIND('-')   FINDSET  FINDFIRST
4188       2766       4485
4125       2844       3859
4594       2797       4281
4156       2813       4968


Hier ist klar das FINDSET der Sieger.
Allerdings such ich noch das Problem, wenn ich einen Key setzte, der alle gefilterten Felder enthält, das dieses langsamer ist.

Re: Daten in einer Tabelle ändern

16. Juli 2009 15:40

testRec2 ist leer das es eine temporäre Tabelle es sollen ja bloß die daten gespeichert werden

also Test SU ist eine Tabelle in der Daten stehen

beispiel

belegnr datum name arbeitseinheit
1 0106 mitarbeiter1 30
usw.

ich möchte jetzt aus diesen daten wenn ein mitarbeiter an einem tag mehrmals vorkommt sollen die arbeitseinheiten gezählt werden und diese daten mit dem datum, name, arbeitseinheit in die temporäre tabelle testRec2 gespeichert werden damit ich diese in einem Report wieder ausgeben kann

Re: Daten in einer Tabelle ändern

16. Juli 2009 15:50

mikka hat geschrieben:Hier ist klar das FINDSET der Sieger.
Allerdings such ich noch das Problem, wenn ich einen Key setzte, der alle gefilterten Felder enthält, das dieses langsamer ist.

Logo, das hatte ich grad voraus gesetzt, Entschuldigung.

Re: Daten in einer Tabelle ändern

16. Juli 2009 15:51

flowerdog hat geschrieben:testRec2 ist leer das es eine temporäre Tabelle es sollen ja bloß die daten gespeichert werden

Dann macht das ganz obige TestRec2.FIND ja überhaupt keinen Sinn. Du würdest schon beim 1. Versuch einen Laufzeitfehler erhalten.

Da du auf meine Frage nach dem Primärschlüssel von TestRec2 nicht eingangen bist, nehme ich an, es ist nur die Zeilennr.
Dann stelle ich mir deinen Quelltext so vor.

Du brauchst eine lokale integer-Variable. Ich nenne sie hier LineNo:


Code:
LineNo := 0;
IF "Test SU".FINDSET THEN BEGIN // Laufe durch alle Zeilen von "Test SU".
  REPEAT
    // schaue nach, ob es bereits einen Datensatz TestRec2 gibt,
    // wo Datum und Beschreibung mit dem aktuellen "Test SU" identisch sind
    TestRec2.RESET;
    TestRec2.SETRANGE(Datum, "Test SU".datum);
    testRec2.SETRANGE(beschreibung,"Test SU".beschreibung);
    IF TestRec2.FINDFIRST THEN BEGIN
      // TestRec2 ist nun mit dem gefundenen Datensatz gefüllt
      testRec2.menge += "Test SU".menge;
      testRec2.MODIFY;
    END ELSE BEGIN
      LineNo += 10000;
      TestRec2.INIT;
      testRec2.zeilennr := LineNo;
      testRec2.datum := "Test SU".datum;
      testRec2.beschreibung := "Test SU".beschreibung;
      testRec2.menge := "Test SU".menge;
      testRec2.einheit := "Test SU".einheit;
      testRec2.INSERT;
    END;
  UNTIL "Test SU".NEXT = 0;
END;


Für gewöhnlich kaue ich hier nicht so viel Quelltext vor, weil es a) mich viel Zeit kostet, b) du relativ wenig dabei lernst.
Du musst wirklich verstehen, warum ich den Quelltext so aufbaue und was die einzelnen Zeilen bedeuten. Wenn Unklarheit herrscht - fragen! :-)

Re: Daten in einer Tabelle ändern

16. Juli 2009 17:02

Danke Natalie! Ich stehe manchmal ein bisschen auf demn schlauch