Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Insert erst beim schließen (https://www.delphipraxis.net/139008-insert-erst-beim-schliessen.html)

Tobinator 21. Aug 2009 17:11

Datenbank: Firebird • Version: 2.1 • Zugriff über: IB

Insert erst beim schließen
 
Hi,

ich bin Neuling und habe ein Problem:
Ich will Daten in eine Firebird-DB einfügen und das klappt nicht so richtig. Hier mein Code:
Code:
    DS_Vorgang.Open;
    DS_Vorgang.Insert;
    DS_Vorgang.FieldByName('Vorgangsnummer').AsString:=s;
    DS_Vorgang.FieldByName('Datum').AsDateTime:=Date;
    DS_Vorgang.FieldByName('Art').asinteger:=2;
    DS_Vorgang.FieldByName('Kunde').AsString:=FRech.LKdNr.Caption;
    DS_Vorgang.FieldByName('TauschApfelKg').AsFloat:=0;
    DS_Vorgang.FieldByName('TauschApfelL').AsInteger:=GesGHA;
    DS_Vorgang.FieldByName('AufkaufA').AsFloat:=0;
    DS_Vorgang.FieldByName('TauschQuitteKg').AsFloat:=0;
    DS_Vorgang.FieldByName('TauschQuitteL').AsInteger:=GesGHQ;
    DS_Vorgang.FieldByName('AufkaufQ').AsFloat:=0;
    DS_Vorgang.FieldByName('BetragNetto').AsFloat:=Sum;
    DS_Vorgang.FieldByName('BetragBrutto').AsFloat:=Sum-SumS;

    DS_Vorgang.Post;
Das wenn ich später mit diesen Daten arbeiten will, kann ich nicht drauf zugreifen (also die gibt's angeblich nicht) und auch mittels IB Expert sind sie in der DB nicht zu sehen. Erst, wenn ich mein Programm schließe, sind die Daten zu sehen. Sie werden also sozusagen erst beim schließen eingefügt.

Kann mir jemand sagen, was ich falsch mache??
Danke schonmal...

mkinzler 21. Aug 2009 17:27

Re: Insert erst beim schließen
 
FireBird arbeitet mit Transaktionen. Du scheinst AutoCommit aktiviert zu haben, deshalb wird beim Schliessen vom Programm die Transaktion abgeschlossen ( Commit). Hättest du das nicht, würden die Änderungen verworfen.
Vor einem Commit/RollBack sind die Änderungen nur innerhalb des Transaktionskontext oder bei dirty read sichtbar.
Ich würde in deinem Fall den Insert in einen eigenen Transaktionskontext einpacken.

Tobinator 21. Aug 2009 18:24

Re: Insert erst beim schließen
 
Danke für die Antwort.

Bei meinem DataSet steht bei DefaultAction TACommit.

Wie packe ich das denn in einen eigenen Transaktionskontext?
(Ich bin wie gesagt ein Neuling was Datenbanken angeht :) )

mkinzler 21. Aug 2009 18:32

Re: Insert erst beim schließen
 
Lege zusätzlich eine TIBTransaction auf das Formular und wähle diese im DataSet aus.
Nun kannst du mit
Delphi-Quellcode:
<Transaktion>.StartTransaction;
die Tranaktion starten und mit
Delphi-Quellcode:
<Transaktion>.Commit;
abschliessen bzw. mit
Delphi-Quellcode:
<Transaktion>.Rollback;
verwerfen

khh 21. Aug 2009 19:30

Re: Insert erst beim schließen
 
Zitat:

Zitat von mkinzler
Lege zusätzlich eine TIBTransaction auf das Formular und wähle diese im DataSet aus.
Nun kannst du mit
Delphi-Quellcode:
<Transaktion>.StartTransaction;
die Tranaktion starten und mit
Delphi-Quellcode:
<Transaktion>.Commit;
abschliessen bzw. mit
Delphi-Quellcode:
<Transaktion>.Rollback;
verwerfen



wobei meiner Meinung nach die Trennung von der DB nach dem Post den selben Eeffekt hat.

Oder gibts da betreffs Zugriffszeit Unterschiede, oder welche Nachteile siehst du gegenüber der Transaktion?

mkinzler 21. Aug 2009 19:36

Re: Insert erst beim schließen
 
Das Trennen schliesst die Tranaktion auch ab oder verwirft sie ( je nach Einstellung). Aber es ist nicht notwendig.
Mit Auschalten eines Motors kann man ja auch Bremsen.

hoika 21. Aug 2009 19:37

Re: Insert erst beim schließen
 
Hallo,

jedes Re-Connect dauert etwas.


Heiko

Tobinator 21. Aug 2009 20:16

Re: Insert erst beim schließen
 
Hi,

danke für die Antworten, aber ich glaub ich verstehs noch nich so richtig. Es ist immernoch der selbe Fehler.

Also ich hab jetzt auf dem einen From je einmal IBDataSet, IBTransaction und IBDatabase.

IBDataSet1 (in meinem code vorhin DS_Vorgang)
Database = IBDatabase1
Transaction = IBTransaction1

IBTransaction1
DefaultAction = TACommit
DefaultDatabase = IBDatabase1

IBDatabase1
DefaultTransaction = IBTransaction1

Code:
  IBTransaction1.StartTransaction;
  IBDataSet1.Open;
  IBDataSet1.Insert;
  IBDataSet1.FieldByName ....
  .... // Felder füllen
  IBDataSet1.Post;
  IBTransaction1.Commit;
Es wird wieder erst beim schließen in die DB eingefügt.

Was soll ich noch ändern??

mkinzler 21. Aug 2009 20:21

Re: Insert erst beim schließen
 
Und wie siehst du, das es erst bei Programmende eingefügt wird?

Tobinator 21. Aug 2009 21:11

Re: Insert erst beim schließen
 
ich gucke nebenbei mit IB Expert in die DB rein. (Ich habs auch zwischendurch immer wieder geöffnet und geschlossen, in der Hoffnung, das es sich aktualisiert, aber es passiert nix).
Mein grundsätzliches Problem ist eigentlich, das ich mit Fastreport auf einem anderen Form damit einen Report erzeugen möchte, aber der bleibt immer leer. Wenn ich das mit einem älteren Datensatz probiere, klappt es problemlos. Das programm muss zwischendurch immer einmal geschlossen werden. Das will ich aber nicht.

mkinzler 21. Aug 2009 21:12

Re: Insert erst beim schließen
 
Mach mal einen Refresh auf dem anderen DataSet

Tobinator 21. Aug 2009 21:26

Re: Insert erst beim schließen
 
hab ich gemacht, bringt aber auch nix...

hier ist mal mein code im andern From. (Die Komponenten sind genauso wie die anderen)

Code:
  IBDataSet1.SelectSQL:=a;
  IBDataSet1.RefreshSQL:=a;

  IBDataSet1.Open;
  IBDataset1.Refresh;

  frxReport1.ShowReport(true);
a ist eine recht komplizierte Abfrage, die funktioniert eigentlich auch, aber ist für den gerade erstellten Datensatz leer.
(die beiden zeilen mit refresh hab ich jetzt erst eingebaut, die bringen aber auhc nix...)

mkinzler 21. Aug 2009 21:33

Re: Insert erst beim schließen
 
Hänge das Projekt mal hier an.

Tobinator 21. Aug 2009 21:45

Re: Insert erst beim schließen
 
Das Projekt ist mit DB ca. 8 MB groß, und das ist mit DSL-Light so ne sache... aber ich kann dir mal die beiden Units schicken, auf die es ankommt:

Code:
unit URech;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, UKunden1, UKunden2, UArtikel1, UArtikel2, StdCtrls, UAbgabe, ComCtrls,
  Grids, DB, IBCustomDataSet, IBDatabase, frxClass, frxDBSet, UQuittung;

type
  TFRech = class(TForm)
    Kunde: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    LKdNr: TLabel;
    LAnr: TLabel;
    LName: TLabel;
    LTel: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    Label10: TLabel;
    LOrt: TLabel;
    LStr: TLabel;
    LDat: TLabel;
    Button1: TButton;
    GroupBox1: TGroupBox;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    LGHA: TLabel;
    LGHQ: TLabel;
    BSuch: TButton;
    EMeng: TEdit;
    Label7: TLabel;
    StringGrid1: TStringGrid;
    GroupBox2: TGroupBox;
    Label11: TLabel;
    Label12: TLabel;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    Label17: TLabel;
    LRestA: TLabel;
    LRestQ: TLabel;
    LSum: TLabel;
    LSumS: TLabel;
    LSumA: TLabel;
    LSumQ: TLabel;
    Button2: TButton;
    Button3: TButton;
    DS_Posten: TIBDataSet;
    IBDatabase1: TIBDatabase;
    IBTransaction1: TIBTransaction;
    procedure Button1Click(Sender: TObject);
    procedure ArtTabelle_show;
    procedure BSuchClick(Sender: TObject);
    procedure EMengExit(Sender: TObject);
    procedure StringGrid1Click(Sender: TObject);
    procedure Gesamt;
    procedure clear;
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

type
  TArtikel=record
    Artikelnummer,
    Bezeichnung,
    Tauschware_str,
    Einheit:String;
    Menge,
    Tauschware,
    Tauschmenge,
    Tauschmenge_ges:integer;
    EzPreis,
    GesPreis,
    Steuer:Currency;
  end;

type
  TArtikeltabelle=Array of TArtikel;

var
  FRech: TFRech;
  GHA, GHQ, RestGHA, RestGHQ, GesGHA, GesGHQ:Integer;
  ArtT:TArtikelTabelle;
  len:integer;
  Sum,SumS:Currency;

  function NextFreePostenID:integer;


implementation

{$R *.dfm}

procedure TFRech.ArtTabelle_show;
var i:integer;
begin
if length(ArtT)>0 then
begin
for i := 0 to Stringgrid1.RowCount - 1 do
  Stringgrid1.Rows[i].Clear;
  Stringgrid1.RowCount:=2;

  Stringgrid1.Cells[0,0]:='Artikelnummer';
  Stringgrid1.Cells[1,0]:='Bezeichnung';
  Stringgrid1.Cells[2,0]:='Menge';
  Stringgrid1.Cells[3,0]:='Einheit';
  Stringgrid1.Cells[4,0]:='Einzelpreis';
  Stringgrid1.Cells[5,0]:='Steuer';
  Stringgrid1.Cells[6,0]:='Gesamtpreis';
  Stringgrid1.Cells[7,0]:='Tauschware';
  Stringgrid1.ColWidths[0]:=90;
  Stringgrid1.ColWidths[1]:=150;
  Stringgrid1.ColWidths[2]:=50;
  Stringgrid1.ColWidths[3]:=70;
  Stringgrid1.ColWidths[4]:=70;
  Stringgrid1.ColWidths[5]:=70;
  Stringgrid1.ColWidths[6]:=70;
  Stringgrid1.ColWidths[7]:=90;

  Stringgrid1.RowCount:=length(ArtT)+1;

  for i := 0 to length(ArtT)-1 do
  begin
    Stringgrid1.Cells[0,i+1]:=ArtT[i].Artikelnummer;
    Stringgrid1.Cells[1,i+1]:=(ArtT[i].Bezeichnung);
    Stringgrid1.Cells[2,i+1]:=(inttostr(ArtT[i].Menge));
    Stringgrid1.Cells[3,i+1]:=(ArtT[i].Einheit);
    Stringgrid1.Cells[4,i+1]:=(FloatToStrF(ArtT[i].EzPreis,ffFixed,10,2));
    Stringgrid1.Cells[5,i+1]:=(FloatToStrF(ArtT[i].Steuer,ffFixed,10,2));
    Stringgrid1.Cells[6,i+1]:=(FloatToStrF(ArtT[i].GesPreis,ffFixed,10,2));
    Stringgrid1.Cells[7,i+1]:=(ArtT[i].Tauschware_str);
  end;
  EMeng.Clear;
end;

end;

function NextFreePostenID:integer;
begin
  with FRech do
  begin
  DS_Posten.SelectSQL.Text:='SELECT * From POSTEN Order By ID';
  DS_Posten.Open;
  DS_Posten.Last;
  result:=DS_Posten.FindField('ID').AsInteger+1;
  end;

end;

procedure TFRech.BSuchClick(Sender: TObject);
var i : integer;
begin


  if FArtikel.ShowModal=mrok then
    begin
      len:=length(ArtT);
      EMeng.SetFocus;
      EMeng.Text:='1';
      EMeng.SelectAll;
      SetLength(ArtT,len+1);
      ArtT[len].Artikelnummer:=resArt.Artikelnummer;
      ArtT[len].Bezeichnung:=resArt.Bezeichnung;
      ArtT[len].Einheit:=resArt.Einheit;
      ArtT[len].Tauschware:=resArt.Tauschware;
      ArtT[len].Tauschmenge:=-resArt.Tauschmenge;
      ArtT[len].EzPreis:=resArt.VKPreisBrutto;
      ArtT[len].Steuer:=resArt.VKPreisBrutto - resArt.VKPreisNetto;
    end;

end;

procedure TFRech.Button1Click(Sender: TObject);
begin
  if FKundenverwaltung.showmodal=mrok then
  begin
    LKdNr.Caption:=resKd.KdNr;
    LAnr.Caption:=Anreden[resKd.Anrede];
    LName.Caption:=resKd.Name1;
    LTel.Caption:=resKd.Tel;
    LStr.Caption:=resKd.Strasse;
    LOrt.Caption:=resKd.PLZ+' '+resKd.Ort;
    LDat.Caption:=DateToStr(date);
    GHA:=GHLadenApfL(resKd.KdNr);
    GHQ:=GHLadenQuittL(resKd.KdNr);
    LGHA.Caption:=FloatToStr(GHLadenApfKG(resKd.KdNr)) +' kg/ ' + IntToStr(GHA)+ ' Liter';
    LGHQ.Caption:=FloatToStr(GHLadenQuittKG(resKd.KdNr)) +' kg/ ' + IntToStr(GHQ)+ ' Liter';
  end;
end;

procedure TFRech.Button2Click(Sender: TObject);  // Der OK-Button
  var s:string;
      i,k :Integer;
begin
if (LKdNr.Caption<>'') and (GesGHA>=-GHA) and (GesGHQ>=-GHQ) then
begin

  IBTransaction1.StartTransaction;

  s:=NextFreeVorgNr;
  with FAbgabe do
  begin
    DS_Vorgang.Open;
    DS_Vorgang.Insert;
    DS_Vorgang.FieldByName('Vorgangsnummer').AsString:=s;
    DS_Vorgang.FieldByName('Datum').AsDateTime:=Date;
    DS_Vorgang.FieldByName('Art').asinteger:=2;
    DS_Vorgang.FieldByName('Kunde').AsString:=FRech.LKdNr.Caption;
    DS_Vorgang.FieldByName('Posten').AsString:='';
    DS_Vorgang.FieldByName('TauschApfelKg').AsFloat:=0;
    DS_Vorgang.FieldByName('TauschApfelL').AsInteger:=GesGHA;
    DS_Vorgang.FieldByName('AufkaufA').AsFloat:=0;
    DS_Vorgang.FieldByName('TauschQuitteKg').AsFloat:=0;
    DS_Vorgang.FieldByName('TauschQuitteL').AsInteger:=GesGHQ;
    DS_Vorgang.FieldByName('AufkaufQ').AsFloat:=0;
    DS_Vorgang.FieldByName('BetragNetto').AsFloat:=Sum;
    DS_Vorgang.FieldByName('BetragBrutto').AsFloat:=Sum-SumS;

    DS_Vorgang.Post;

  end;


  k:=NextFreePostenID;
  DS_Posten.Open;

  for i := 0 to length(ArtT) - 1 do
    begin
      DS_Posten.Insert;
      DS_Posten.FieldValues['ID']:=k+i;
      DS_Posten.FieldValues['Vorgangsnummer']:=s;
      DS_Posten.FieldValues['Artikelnummer']:=ArtT[i].Artikelnummer;
      DS_Posten.FieldValues['Menge']:=ArtT[i].Menge;
      DS_Posten.FieldValues['BetragNetto']:=ArtT[i].GesPreis;
      DS_Posten.FieldValues['BetragBrutto']:=ArtT[i].GesPreis-ArtT[i].Steuer;
      DS_Posten.Post;
    end;

  IBTransaction1.Commit;

  modalresult:=mrOk;
  clear;
  hide;
  showrep(s);
end;

end;

procedure TFRech.Button3Click(Sender: TObject);
begin
  clear;
  hide;
end;

procedure TFRech.clear;
var i:integer;
begin
  LKdNr.Caption:='';
  LAnr.Caption:='';
  LName.Caption:='';
  LTel.Caption:='';
  LStr.Caption:='';
  LOrt.Caption:='';
  LDat.Caption:='';
  GHA:=0;
  GHQ:=0;
  LGHA.Caption:='';
  LGHQ.Caption:='';
  for i := 0 to length(ArtT) - 1 do
  begin
    ArtT[i].Artikelnummer:='';
    ArtT[i].Bezeichnung:='';
    ArtT[i].Tauschware_str:='';
    ArtT[i].Einheit:='';
    ArtT[i].Menge:=0;
    ArtT[i].Tauschware:=0;
    ArtT[i].Tauschmenge_ges:=0;
    ArtT[i].EzPreis:=0;
    ArtT[i].GesPreis:=0;
    ArtT[i].Steuer:=0;
  end;

  SetLength(ArtT,0);

  LRestA.Caption:='';
  LRestQ.Caption:='';

  LSum.Caption:='';
  LSumS.Caption:='';
  LSumA.Caption:='';
  LSumQ.Caption:='';
  EMeng.Clear;

  for i := 0 to Stringgrid1.RowCount - 1 do
  Stringgrid1.Rows[i].Clear;
  Stringgrid1.RowCount:=2;

  ResKd:=K2;
  ResArt:=A2;

end;

procedure TFRech.EMengExit(Sender: TObject);
begin
  if resArt.Artikelnummer<>'' then
    begin
    ArtT[len].Menge:=StrToIntDef(EMeng.Text,0);
    ArtT[len].Tauschmenge_ges:=StrToIntDef(EMeng.Text,0)*ArtT[len].Tauschmenge;
    ArtT[len].GesPreis:=StrToIntDef(EMeng.Text,0)*ArtT[len].EzPreis;
    ArtT[len].Tauschware_str:=Tauschwaren[ArtT[len].Tauschware]+' ('+InttoStr(StrToIntDef(EMeng.Text,0)*ArtT[len].Tauschmenge)+' Liter)';
    end
    else
    begin
    //ArtT[Stringgrid1.Row-1].Menge:=StrToIntDef(EMeng.Text,0);
    //ArtT[Stringgrid1.Row-1].Tauschmenge_ges:=StrToIntDef(EMeng.Text,0)*ArtT[len].Tauschmenge;
    //ArtT[Stringgrid1.Row-1].GesPreis:=StrToIntDef(EMeng.Text,0)*ArtT[len].EzPreis;
    //ArtT[Stringgrid1.Row-1].Tauschware_str:=Tauschwaren[ArtT[len].Tauschware]+' ('+InttoStr(StrToIntDef(EMeng.Text,0)*ArtT[len].Tauschmenge)+' Liter)';
    end;
  ArtTabelle_show;
  resArt:=A2;
  gesamt;
end;

procedure TFRech.Gesamt;
var i:integer;
begin
  RestGHA:=0;
  RestGHQ:=0;
  GesGHA:=0;
  GesGHQ:=0;
  Sum:=0;
  SumS:=0;

  for i := 0 to length(ArtT) - 1 do
  begin
  if ArtT[i].Tauschware=1 then GesGHA:=GesGHA+ArtT[i].Tauschmenge_ges;
  if ArtT[i].Tauschware=2 then GesGHQ:=GesGHQ+ArtT[i].Tauschmenge_ges;
  Sum:=Sum+ArtT[i].GesPreis;
  SumS:=SumS+ArtT[i].Steuer;
  end;

  RestGHA:=GHA+GesGHA;
  RestGHQ:=GHQ+GesGHQ;

  LRestA.Caption:=inttostr(RestGHA)+' Liter';
  LRestQ.Caption:=inttostr(RestGHQ)+' Liter';

  LSum.Caption:=floattostrf(Sum,ffFixed,10,2);
  LSumS.Caption:=floattostrf(SumS,ffFixed,10,2);
  LSumA.Caption:=inttoStr(GesGHA)+' Liter';
  LSumQ.Caption:=inttoStr(GesGHQ)+' Liter';

end;

procedure TFRech.StringGrid1Click(Sender: TObject);
begin
if Stringgrid1.Row>0 then
  EMeng.Text:=inttostr(ArtT[Stringgrid1.Row-1].Menge);
end;

end.
Die Unit, die es einfügt.

Code:
unit UQuittung;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, frxClass, frxDBSet, DB, IBCustomDataSet, IBQuery, StdCtrls,
  IBDatabase;

type
  TFQuittung = class(TForm)
    frxReport1: TfrxReport;
    frxDBDataset5: TfrxDBDataset;
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    IBDatabase1: TIBDatabase;
    IBTransaction1: TIBTransaction;
    IBDataSet1: TIBDataSet;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  FQuittung: TFQuittung;

  procedure showrep(VgNr:String);

implementation

{$R *.dfm}

procedure showrep(VgNr:String);
var a : TStrings;
begin

a:=TStringList.Create;
with FQuittung do
begin
  show;
  a.Clear;
  a.Add('SELECT V.VORGANGSNUMMER, V.DATUM, V.KUNDE, V.TAUSCHAPFELL, V.TAUSCHQUITTEL, V.BETRAGBRUTTO, ' + 'P.VORGANGSNUMMER, P.ARTIKELNUMMER, P.MENGE, P.BETRAGBRUTTO, A.ARTIKELNUMMER, A.BEZEICHNUNG, A.VKPREISBRUTTO, K.KUNDENNUMMER, K.ANREDE, K.NAME1, K.TEL, K.STRASSE, K.PLZ, K.ORT');
  a.Add('FROM');
  a.Add(' VORGANG V,');
  a.Add(' POSTEN P,');
  a.Add('  ARTIKEL A,');
  a.Add(' KUNDEN K');
  a.Add('WHERE');
  a.Add(' V.VORGANGSNUMMER = '+chr(39)+VgNr+chr(39)+' AND');
  a.Add(' P.VORGANGSNUMMER = V.Vorgangsnummer AND');
  a.Add(' A.ARTIKELNUMMER = P.Artikelnummer AND');
  a.Add(' V.KUNDE = K.KUNDENNUMMER');
  IBDataSet1.SelectSQL:=a;
  IBDataSet1.RefreshSQL:=a;

  IBDataSet1.Open;
  IBDataset1.Refresh;

  frxReport1.ShowReport(true);
  Memo1.Lines:=IBDataSet1.SelectSQL;
  showmessage(IBDataSet1.FieldByName('Vorgangsnummer').AsString);
end;


end;

procedure TFQuittung.Button1Click(Sender: TObject);
begin
  frxReport1.ShowReport(true);
end;

procedure TFQuittung.Button2Click(Sender: TObject);
begin
  showrep('V.00073'); // der letzte Datensatz
end;

end.
Die Unit, die den Report erstellen soll.

Zur erklärung: Das soll eine Art Buchhaltungs-Programm werden für ein Lohnobst annahme- und umtauschstelle.
(Ich weis, das es noch nicht wirklich effektiv arbeitet, aber es muss erstmal fertig werden. Überarbeitet wir später :) )

mkinzler 21. Aug 2009 22:02

Re: Insert erst beim schließen
 
Am Besten packst du die Units mitsamt der Formualre )dfm) und der DB in eine Zip und hängst diese an. Ich würde die Abfragen auch zur Entwurfstzeit setzen und nicht jedesmal neu. Zudem ist deine Methode zur Ermittlung der nächsten ID nicht wasserdicht; hier würde ich lieber den Weg über einen Generator(Sequenz) gehen.

Tobinator 21. Aug 2009 22:29

Re: Insert erst beim schließen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ha, ich hab den _history-Ordner rausgenommen und jetzt gehts einigermaßen (hätte nicht gedacht, das das als zip so klein ist...)

Das mit dem Generator hab ich auch schon überlegt, dann hab ich das mal probiert und bin nicht so recht damit zurecht gekommen. Das ist dann eines der ersten Sachen zum überarbeiten.

Danke schonmal für deine Hilfe :thumb: :thumb:

Mackhack 22. Aug 2009 05:27

Re: Insert erst beim schließen
 
Fehlt da kein ExecSQL in seinem Quelltext?

hoika 22. Aug 2009 07:07

Re: Insert erst beim schließen
 
Hallo,

nein, fehlt nicht. Ist ein DataSet (ich hasse die Dinger ;) )
Dort reicht das Post (Thread #1).


Heiko

Tobinator 23. Aug 2009 00:51

Re: Insert erst beim schließen
 
Hat schon einer ne Lösung??

hoika 23. Aug 2009 13:50

Re: Insert erst beim schließen
 
Hallo,

du solltest mal unsere Vorschläge beachten.
In UKunden1 gibt es zwar eine IBTransaction1,
sie wird aber nicht benutzt (StartTransaction/Commit).

D.h. die Daten sind Teil einer Transaktion.
die erst mit dem DB-Close commited werden.
Deshalb kann sie auch IBExpert erst nach Programm-Ende "sehen".


ein Bsp.

dein Code

Delphi-Quellcode:
procedure TFKundenverwaltung.Button3Click(Sender: TObject);
begin
  k:=k2;
  k.KdNr:=NextFreeKdNr;
  SetKunde(k);
  if FKundenbearbeiten.ShowModal=mrOK then
  begin
    DS_Kunden.Insert;
    SetKundeToDS(GetKunde);
    DS_Kunden.Post;
  end;
end;
und nun mit Transaktionsverwaltung
Delphi-Quellcode:
procedure TFKundenverwaltung.Button3Click(Sender: TObject);
begin
  k:=k2;
  k.KdNr:=NextFreeKdNr;
  SetKunde(k);
  if FKundenbearbeiten.ShowModal=mrOK then
  begin
    Kunden.Transaction.StartTransaction;  // IBTransaction1.StartTransaction ist hier das gleiche
    DS_Kunden.Insert;
    SetKundeToDS(GetKunde);
    DS_Kunden.Post;
    Kunden.Transaction.Commit;
  end;
end;

Hieko

Tobinator 23. Aug 2009 14:01

Re: Insert erst beim schließen
 
Ja, ich weis, das noch einiges zu ändern ist, aber das kommt später.

Mein aktuelles Problem ist, das ich eine Rechnung erstelle (URech), also Kunde laden, Artikel laden, und dann OK klicken. Dann sollte sich ein Report öffenen, so das man den Report ausdrucken kann. Der Report greift dann auf die DB zu, in der die aktuellen Daten aber noch nicht stehen.
Aber danke für den Tipp. Ich werde das mit dem Transaction.commit auch in den anderen Forms ändern. Aber das löst ja nicht mein grundsätzliches Problem...

Aber ich versuche gerade das ganze ohne DB zu lösen und die Daten direkt zu übergeben.

Es wäre aber trotzdem schön, wenn das mit der DB klappen würde... das würde mit Arbeit ersparen. :)

mkinzler 23. Aug 2009 14:30

Re: Insert erst beim schließen
 
Das ExecSql in eine Start/Commit einzubetten sollte doch kein großes Problem sein.
Ich habe deinen Code bisher nur kurz überflogen und gesehen, das du pro Form eine TDataBase verwendest.
Ich würde die durch eine ersetzen, welche ich mitsamt den ganzen DataSets in ein Datenmodul verfrachten

hoika 24. Aug 2009 08:29

Re: Insert erst beim schließen
 
Hallo,

Zitat:

Ich werde das mit dem Transaction.commit auch in den anderen Forms ändern. Aber das löst ja nicht mein grundsätzliches Problem...
Alsooooooo

Das ursprüngliche Problem war ja wohl,
dass geänderte Daten nicht im Report erscheinen.

ABER
Ohne das explizite Commit ist das das Standardverhalten
einer (Firebird)-Datenbank !!!
Ohne Commit sehen alle neueren Abfragen (auch des gleichen Programms)
die geänderten Daten nicht, sofern sie nicht im Context der gleichen
Transaktion laufen.
Das ist gewollt.


Nächste Frage: Wie übergibst du denn die Daten an den Report ?


Heiko

Tobinator 24. Aug 2009 10:28

Re: Insert erst beim schließen
 
Hi,

Ich hab mich jetzt entschieden, das ganze nicht über einen Report zu machen sonder als HTML, die ich dann ausdrucke... Die Daten dazu übergebe ich direkt, also nicht über die DB. Ich werde jetzt alles nochmal überarbeiten und dabei auf die Transactionen achten. Also ihr braucht nicht weiter nach dem Problem suchen... Aber danke für eure hilfe...

:thumb: :thumb:

mkinzler 24. Aug 2009 10:46

Re: Insert erst beim schließen
 
Warum auch einfach, wenn es kompliziert geht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:55 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz