Einzelnen Beitrag anzeigen

ioster

Registriert seit: 15. Aug 2008
84 Beiträge
 
Delphi 10.3 Rio
 
#1

OnChange behindert Post

  Alt 15. Jan 2020, 16:37
Datenbank: MS SQL Server • Version: 2008 • Zugriff über: FireDAC
Hallo zusammen,

nachdem ich grundlegende Probleme mit der FireDAC-Connection überwunden habe, ist nun bei der Entwicklung einer Belegmaske ein Fehler aufgetreten, der im Zusammenhang mit dem OnChange-Ereignis von TField angesiedelt ist.

Ich habe für den Beleg zwei Tabellen in denen Kopf- und Positionsdaten gespeichert werden. Im AfterOpen der Tabellen habe ich an das OnChange-Ereignis von bestimmten Feldern Prozeduren gehängt, um Adress- und Artikelstammdaten nachzulesen oder den Gesamtpreis von Position und Gesamtbeleg zu aktualisieren.

Delphi-Quellcode:
if Dataset.FindField('ArtNr') <> nil then
      Dataset.FieldByName('ArtNr').OnChange := ArtikelEingabe;

    if Dataset.FindField('VKNetto') <> nil then
      Dataset.FieldByName('VKNetto').OnChange := PreisBerechnung;
    if Dataset.FindField('Anzahl') <> nil then
      Dataset.FieldByName('Anzahl').OnChange := PreisBerechnung;
    if Dataset.FindField('Positionsrabatt1') <> nil then
      Dataset.FieldByName('Positionsrabatt1').OnChange := PreisBerechnung;
    if Dataset.FindField('Positionsrabatt2') <> nil then
      Dataset.FieldByName('Positionsrabatt2').OnChange := PreisBerechnung;
    if Dataset.FindField('Positionsrabatt3') <> nil then
      Dataset.FieldByName('Positionsrabatt3').OnChange := PreisBerechnung;
    if Dataset.FindField('Positionsrabatt4') <> nil then
      Dataset.FieldByName('Positionsrabatt4').OnChange := PreisBerechnung;
Die Preisberechnung funktioniert auch wunderbar. Allerdings habe ich das Problem, dass die Daten aus der Kopftabelle nicht richtig weggeschrieben werden. Die vorab eingegebenen Adressstammdaten und Belegsummen sind nach dem Navigieren in der Datenmenge weg.

Nun bin ich selber schon auf die Idee gekommen, den Status des Datasets zu prüfen und ein Post abzusenden, sofern die Datenmenge sich im dsedit oder dsinsert befindet. Das habe ich die Routine für die Preisberechnung eingebaut und nun auch in das OnBeforeInsert und OnBeforeEdit der Positionstabelle. Offenbar scheinen die Feldinhalte der Kopftabelle schon vorher abhanden gekommen zu sein. Auf dem Bildschirm werden die Werte solange richtig angezeigt bis man einen anderen Beleg aufruft.

Ein ähnliches Szenario mit 1:n-Beziehungen zwischen Tabellen habe ich auch in anderen Masken wie Artikel- und Adressstamm. Dort tritt dieses Problem allerdings nicht auf, aber an den Tabellen und Feldern hängen keine OnChange-Ereignisse.

Die Preisberechnung sieht folgendermaßen aus, wobei ich einräume, dass die ein oder andere Feinheit in der Berechnung fehlt. Das ist aber für die Speicherung der Daten nicht weiter relevant.

Delphi-Quellcode:
procedure TDatenmodul.Preisberechnung(Field: TField);
  var
    PosRab : double;
    PosZuschlag : double;
    VKNetto : double;
    Zaehler : integer;
    RabBetrag : double;
    ZuschlBetrag : double;
    MerkGesNetto : double;
    MerkGesBrutto : double;
    MerkUSt : double;
  begin
    RabBetrag := 0;
    ZuschlBetrag := 0;

    MerkGesNetto := Field.DataSet.FieldByName('VKNettoGesamt').AsFloat;
    MerkGesBrutto := Field.DataSet.FieldByName('VKBruttoGesamt').AsFloat;
    MerkUst := Field.DataSet.FieldByName('USt').AsFloat;

    with Field.DataSet Do
      begin
        VKNetto := Fieldbyname('Anzahl').asfloat * Fieldbyname('VKNetto').asfloat;

        for Zaehler := 1 to 4 do
          begin
            if (Fieldbyname('Positionsrabatt' + inttostr(Zaehler)).AsFloat <> 0) then
              begin
                if (Fieldbyname('Rabattart' + inttostr(Zaehler)).AsString = '=') then
                  PosRab := Fieldbyname('Positionsrabatt' + inttostr(Zaehler)).asfloat
                else
                  PosRab := VKNetto * Fieldbyname('Positionsrabatt' + inttostr(Zaehler)).AsFloat / 100;

                VKNetto := VKNetto - PosRab;

                RabBetrag := RabBetrag + PosRab;
              end;
          end;

        for Zaehler := 1 to 4 do
          begin
            if (Fieldbyname('Zuschlag' + inttostr(Zaehler)).AsFloat <> 0) then
              begin
                if (Fieldbyname('Zuschlagart' + inttostr(Zaehler)).AsString = '=') then
                  PosZuschlag := Fieldbyname('Zuschlag' + inttostr(Zaehler)).asfloat
                else
                  PosZuschlag := VKNetto * Fieldbyname('Zuschlag' + inttostr(Zaehler)).AsFloat / 100;

                VKNetto := VKNetto + PosZuschlag;

                ZuschlBetrag := PosZuschlag;
              end;
          end;

        if not(State in [dsedit, dsinsert]) then
          Edit;

        Fieldbyname('VKNettoGesamt').asfloat := VKNetto;
        Fieldbyname('RabattBetrag').AsFloat := RabBetrag;
        Fieldbyname('ZuschlagsBetrag').AsFloat := ZuschlBetrag;

        Fieldbyname('Ust').AsFloat := Fieldbyname('VKNettoGesamt').AsFloat * Fieldbyname('SteuerProzent').AsFloat / 100;
        Fieldbyname('VKBruttoGesamt').AsFloat := Fieldbyname('VKNettoGesamt').asfloat + Fieldbyname('Ust').asfloat;

        Post;
      end;

    with Datenmodul.AngebotKopf Do
      begin
        Edit;
        Fieldbyname('VKNetto').AsFloat := Datenmodul.AngebotKopf.Fieldbyname('VKNetto').AsFloat - MerkGesNetto + Field.DataSet.FieldByName('VKNettoGesamt').asfloat;
        Fieldbyname('VKBrutto').AsFloat := Datenmodul.AngebotKopf.Fieldbyname('VKBrutto').AsFloat - MerkGesBrutto + Field.DataSet.FieldByName('VKBruttoGesamt').asfloat;
        Fieldbyname('Ust').AsFloat := Datenmodul.AngebotKopf.Fieldbyname('USt').AsFloat - MerkUST + Field.DataSet.FieldByName('USt').asfloat;

        if Field.Dataset.FieldByName('Steuerschluessel').Asinteger > 0 then
          Fieldbyname('USt' + inttostr(Field.Dataset.FieldByName('Steuerschluessel').Asinteger)).asfloat := Fieldbyname('USt' + inttostr(Field.Dataset.FieldByName('Steuerschluessel').Asinteger)).asfloat - MerkUSt + Field.DataSet.FieldByName('USt').asfloat;

        Post;
      end;
  end;
Viele Grüße
Ingo
  Mit Zitat antworten Zitat