I am starting my first app that needs an embedded database, ability to import a CSV into a table and display the results into a Grid. I used the Live Binding Wizard to link my grid to a BindSourceDB. Here are the basic components I am using:
BindingsList1: TBindingsList;
LinkFillControlToField1: TLinkFillControlToField;
BindSourceDB1: TBindSourceDB;
FireTaskList: TFDConnection;
FDTableTask: TFDTable;
FDQuery: TFDQuery;
FDGUIxWaitCursor1: TFDGUIxWaitCursor;
FDPhysIBDriverLink1: TFDPhysIBDriverLink;
FDTableTaskDATE: TDateField;
FDTableTaskDESCRIPTION: TStringField;
FDTableTaskORIGDESC: TStringField;
FDTableTaskAMOUNT: TIntegerField;
FDTableTaskTYPE: TStringField;
FDTableTaskCATEGORY: TStringField;
FDTableTaskACCTNAME: TStringField;
FDTableTaskLABELS: TStringField;
FDTableTaskNOTES: TMemoField;
FDBatchMove1: TFDBatchMove;
FDBatchMoveTextReader1: TFDBatchMoveTextReader;
FDBatchMoveDataSetWriter1: TFDBatchMoveDataSetWriter;
OpenDialog1: TOpenDialog;
Grid1: TGrid;
LinkGridToDataSourceBindSourceDB1: TLinkGridToDataSource;
1st problem, it is a real slow process importing a file with 7 total columns and total of 5500 lines or records in the file. I setup my FDBatchMoveTextReader for CSV file adding the fields of the file. I Setup my FDBatchMoveDataSetWriter to write to the Dataset FDTableTask and assigned my table's fields to it.
Here is my basic code:
if OpenDialog1.Execute then
begin
ShowMessage('Start read'); // more then 5 secods before this displays (sometimes)
FDBatchMoveTextReader1.FileName := OpenDialog1.FileName;
ShowMessage('Start Move'); // Dispalys instantly
FDBatchMove1.Execute;
Showmessage('done'); //About 25 seconds before this displays
end;
It works but takes very long. Doing this in Delphi 5 and using DBISAM and a CSV Import component, the whole process is like 5 seconds. I have just the default settings on the FDBatchMove component. Not only does it take long, but I am replacing the data in the FDTableTask table by setting the FDBatchMove1.Options to [poClearDest,poIdentityInsert].
The process is slow and the grid never gets repopulated with the new file data until I close and reopen the app. How can I make this process faster and display the new data in the grid when the process complete?
Update In view of your comments, I've updated this a third time to show an example which is as close as I'm prepared to get to your code and which does not seem to suffer the problems you say you are having. I can only suggest that you try it yourself and then try and pin down why your own project does not behave in the same way. I am not going to spend any more time on this.
Using Live Bindings is way slower than using traditional db-aware components.
That said, I'm afraid I cannot reproduce your problems. I set up a multi-device FMX project as shown in the code and DFM extract below. To make it as self-contained as possible, I've put all the components and code in a single form unit and the code generates the CSV file to import.
As you'll see if you compile and run the project, the app starts with the StringGrid containing 3 rows, and clicking the ImportCSV button generates and imports 9997 extra rows. This takes no more than a couple of seconds on my laptop.
Note that I don't see any noticeable change in the speed of the ImportCSV
procedure, if I comment out the calls to DisableControls and EnableControls. This surprised me slightly, but perhaps TFDBatchMove does this or similar internally.
This sample app shows a quirk of LiveBindings (in Seattle at least). Without the calls to FDMemTable1.First
in FormCreate
and ImportCSV
, the StringGrid only shows row 3 after FormCreate
and rows 1, 2 and 10000 after ImportCSV
.
Code:
type
TForm1 = class(TForm)
FDGUIxWaitCursor1: TFDGUIxWaitCursor;
StringGrid1: TStringGrid;
BindSourceDB1: TBindSourceDB;
BindingsList1: TBindingsList;
FDMemTable1: TFDMemTable;
FDMemTable1ID: TIntegerField;
FDMemTable1Name: TStringField;
LinkGridToDataSource1: TLinkGridToDataSource;
FDBatchMove1: TFDBatchMove;
FDBatchMoveDataSetWriter1: TFDBatchMoveDataSetWriter;
Button1: TButton;
BindNavigator1: TBindNavigator;
FDBatchMoveTextReader1: TFDBatchMoveTextReader;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
procedure ImportCSV;
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
procedure TForm1.Button1Click(Sender: TObject);
begin
ImportCSV;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FDMemTable1.IndexFieldNames := 'ID';
FDMemTable1.CreateDataSet;
FDMemTable1.InsertRecord([1, 'One']);
FDMemTable1.InsertRecord([2, 'Two']);
FDMemTable1.InsertRecord([3, 'Three']);
FDMemTable1.First;
end;
procedure TForm1.ImportCSV;
var
AFileName : String;
TL : TStringList;
i : Integer;
begin
AFileName := 'c:\temp\book1.csv';
try
TL := TStringList.Create;
for i := 4 to 10000 do
TL.Add(IntToStr(i) + ',' + 'Row ' + IntToStr(i));
TL.SaveToFile(AFileName);
FDMemTable1.DisableControls;
FDBatchMoveTextReader1.FileName := AFileName;
FDBatchMove1.Execute;
FDMemTable1.First;
finally
FDMemTable1.EnableControls;
TL.Free;
end;
end;
DFM
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 480
ClientWidth = 429
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
OnCreate = FormCreate
DesignerMasterStyle = 0
object StringGrid1: TStringGrid
Position.X = 8.000000000000000000
Position.Y = 8.000000000000000000
Size.Width = 409.000000000000000000
Size.Height = 201.000000000000000000
Size.PlatformDefault = False
TabOrder = 3
RowCount = 100
RowHeight = 21.000000000000000000
Viewport.Width = 389.000000000000000000
Viewport.Height = 176.000000000000000000
end
object Button1: TButton
Position.X = 160.000000000000000000
Position.Y = 288.000000000000000000
TabOrder = 10
Text = 'Button1'
OnClick = Button1Click
end
object BindNavigator1: TBindNavigator
Position.X = 8.000000000000000000
Position.Y = 216.000000000000000000
Size.Width = 240.000000000000000000
Size.Height = 25.000000000000000000
Size.PlatformDefault = False
TabOrder = 19
DataSource = BindSourceDB1
xRadius = 4.000000000000000000
yRadius = 4.000000000000000000
end
object FDGUIxWaitCursor1: TFDGUIxWaitCursor
Provider = 'FMX'
Left = 352
Top = 48
end
object BindSourceDB1: TBindSourceDB
DataSet = FDMemTable1
ScopeMappings = <>
Left = 160
Top = 48
end
object BindingsList1: TBindingsList
Methods = <>
OutputConverters = <>
Left = 272
Top = 48
object LinkGridToDataSource1: TLinkGridToDataSource
Category = 'Quick Bindings'
DataSource = BindSourceDB1
GridControl = StringGrid1
Columns = <>
end
end
object FDMemTable1: TFDMemTable
FetchOptions.AssignedValues = [evMode]
FetchOptions.Mode = fmAll
ResourceOptions.AssignedValues = [rvSilentMode]
ResourceOptions.SilentMode = True
UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates]
UpdateOptions.CheckRequired = False
UpdateOptions.AutoCommitUpdates = True
Left = 72
Top = 48
object FDMemTable1ID: TIntegerField
FieldName = 'ID'
end
object FDMemTable1Name: TStringField
FieldName = 'Name'
end
end
object FDBatchMove1: TFDBatchMove
Reader = FDBatchMoveTextReader1
Writer = FDBatchMoveDataSetWriter1
Mappings = <>
LogFileName = 'c:\temp\Data.log'
Left = 72
Top = 136
end
object FDBatchMoveDataSetWriter1: TFDBatchMoveDataSetWriter
DataSet = FDMemTable1
Left = 352
Top = 136
end
object FDBatchMoveTextReader1: TFDBatchMoveTextReader
DataDef.Fields = <>
Left = 192
Top = 136
end
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.