I have "briefcase model application". Clientdataset reads data from xml-file. After closing modified data are saved in the xml-file. When click on "applyUpdate" button, data are saved in firebird db.
If I don't exit program then ApplyUpdate works properly and commits delta-packet in db but sometimes, after closing-opening program 3- 4-5 times, for no clear reason delta becomes empty and after that if I click on "apply" button ApplyUpdates(-1) operator causes exception "access violation".
Delphi 10.4, update 2. Firebird3.
Project and db files on google drive: https://drive.google.com/drive/folders/1UvtGmaWLdmmSYQITWpEvp-BwRNmw9VEL?usp=sharing
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB, FireDAC.Stan.Intf,
FireDAC.Stan.Option, FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS,
FireDAC.Phys.Intf, FireDAC.DApt.Intf, FireDAC.Stan.Async, FireDAC.DApt,
Datasnap.DBClient, FireDAC.Comp.DataSet, FireDAC.Comp.Client,
Datasnap.Provider, Vcl.StdCtrls, Vcl.Buttons, Vcl.ComCtrls, Vcl.Grids,
Vcl.DBGrids, FireDAC.UI.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool,
FireDAC.Phys, FireDAC.Phys.FB, FireDAC.Phys.FBDef, FireDAC.VCLUI.Wait, MidasLib;
type
TForm1 = class(TForm)
LabelStatus: TLabel;
LabelChangeCount: TLabel;
DBGrid: TDBGrid;
bApply: TBitBtn;
DBGrid2: TDBGrid;
bClose: TButton;
bOpen: TButton;
bMerge: TBitBtn;
DataSource1: TDataSource;
DataSetProvider1: TDataSetProvider;
qGoods: TFDQuery;
cdsGoods: TClientDataSet;
DataSource2: TDataSource;
FDConnection1: TFDConnection;
FDTransaction1: TFDTransaction;
qGoodsGOODS_ID: TIntegerField;
qGoodsGOOD: TWideStringField;
qGoodsQNT: TWideStringField;
procedure bApplyClick(Sender: TObject);
procedure bCloseClick(Sender: TObject);
procedure bOpenClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure cdsGoodsAfterPost(DataSet: TDataSet);
procedure DataSource1DataChange(Sender: TObject; Field: TField);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
FN: TFileName;
MySavePoint: integer;
Modified: boolean;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
qGoods.Open;
FN:= ExtractFilePath(ParamStr(0)) + 'cds.xml';
cdsGoods.filename:= FN;
cdsGoods.Close;
cdsGoods.open;
MySavePoint:= cdsGoods.SavePoint;
end;
procedure TForm1.bApplyClick(Sender: TObject);
begin
cdsGoods.ApplyUpdates(-1);
qGoods.Refresh;
MySavePoint:=cdsGoods.SavePoint;
Modified:= false;
end;
procedure TForm1.bCloseClick(Sender: TObject);
begin
cdsGoods.Close;
end;
procedure TForm1.bOpenClick(Sender: TObject);
begin
cdsGoods.Open;
end;
procedure TForm1.cdsGoodsAfterPost(DataSet: TDataSet);
begin
Modified:= true;
end;
procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
begin
case cdsGoods.UpdateStatus of
usUnmodified: labelStatus.Caption:='record didnt change';
usModified: labelStatus.Caption:='record was modified';
usInserted: labelStatus.Caption:='record was inserted';
usDeleted: labelStatus.Caption:='record was deleted';
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
qGoods.close;
cdsGoods.Close;
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if Modified then case application.MessageBox(PwideChar('Data were changed. Save changes?'), '', MB_YESNOCANCEL+MB_ICONQUESTION) of
IDCancel: CanClose:=false;
IDNo: cdsGoods.SavePoint:=MySavePoint;
// IDYES- no needed. Cds is saved auomatically after close
// cdsGoods.saveToFile(FN);
end;
end;
end.