我正在开始我的第一个需要嵌入式数据库的应用程序,能够将CSV导入表格并将结果显示到网格中。我使用Live Binding Wizard将我的网格链接到BindSourceDB。以下是我使用的基本组件:
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;
第一个问题,导入文件总共7列,总共5500行或记录的文件是一个非常缓慢的过程。我为我的FDBatchMoveTextReader设置了添加文件字段的CSV文件。我设置我的FDBatchMoveDataSetWriter来写入数据集FDTableTask并将表格的字段分配给它。
这是我的基本代码:
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;
它有效,但需要很长时间。在Delphi 5中使用DBISAM和CSV Import组件执行此操作,整个过程就像5秒钟。我只有FDBatchMove组件的默认设置。这不仅需要很长时间,而且我通过将FDBatchMove1.Options设置为[poClearDest,poIdentityInsert]来替换FDTableTask表中的数据。
过程很慢,网格永远不会重新填充新的文件数据,直到我关闭并重新打开应用程序。如何在流程完成后更快地完成此过程并在网格中显示新数据?
答案 0 :(得分:1)
更新鉴于您的评论,我已经第三次更新了这个,以展示一个尽可能接近我的代码并且似乎没有受到影响的示例你说你遇到的问题。我只能建议你自己尝试,然后尝试确定你自己的原因 项目的行为方式不同。我不打算再花钱了 时间在此。
使用Live Bindings 方式比使用传统的db-aware组件慢。
那就是说,我恐怕无法重现你的问题。我设置了一个多设备FMX 项目如下面的代码和DFM提取。为了做到这一点 尽可能自包含,我已将所有组件和代码放在一个单独的组件中 表单单元,代码生成要导入的CSV文件。
正如您将看到编译和运行项目一样,应用程序以 StringGrid包含3行,并单击ImportCSV按钮生成和 进口额外9997行。这花了不到几秒钟就可以了 笔记本电脑。
请注意,ImportCSV
的速度没有任何明显变化
过程,如果我注释掉对DisableControls和EnableControls的调用。这个
我略微感到惊讶,但也许TFDBatchMove在内部做了这个或类似的事情。
此示例应用程序显示了LiveBindings的怪癖(至少在西雅图)。没有
在FDMemTable1.First
和FormCreate
,StringGrid中调用ImportCSV
仅在FormCreate
后显示第3行,在ImportCSV
后显示第1,2和10000行。
代码:
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