简体   繁体   English

Delphi-FireDAC事件

[英]Delphi - FireDAC events

I have the following form in Delphi: 我在Delphi中有以下表格:

在此处输入图片说明

Note: I am using FireDAC database driver, and TDBGrid component. 注意:我正在使用FireDAC数据库驱动程序和TDBGrid组件。

Note: I am using test column names and data for this question. 注意:我正在针对此问题使用测试列名称和数据。 If you want, I can send you complete database tables, but they are in Serbian. 如果需要,我可以向您发送完整的数据库表,但是它们在塞尔维亚语中。

Here is a code snippet for Load values event (combo box), that works: 这是有效的“ 加载值”事件(组合框)的代码段:

procedure TForm2.Button4Click(Sender: TObject);
begin
with DataModule1.FDQuery1 do
begin
 close;
 sql.Clear;
 sql.Text:='select distinct Department from protocols';
 open;

 DataModule1.FDQuery1.First;

 while not DataModule1.FDQuery1.Eof do
 begin
 ComboBox1.Items.Create.Add(DataModule1.FDQuery1['Department']);

 DataModule1.FDQuery1.Next;
 end;


end;

end;

For the View (records) , the following is working: 对于View(记录) ,以下工作正常:

procedure TForm2.Button2Click(Sender: TObject);
begin
DataModule1.FDQuery1.sql.Text:= ' select protocols.ID_Document, protocols.Document, protocols.ID_Customer, protocols.Customer, protocols.Department, protocols.Date, protocols.Protocol, protocols.ID_Registrator, protocols.Registrator '
+ ' from protocols '
+ ' inner join documents on documents.ID_Document=protocols.ID_Document '
+ ' inner join registrators on registrators.ID_Registrator=protocols.ID_Registrator '
+ ' inner join customers on customers.ID_Customer=protocols.ID_Customer '
+ ' inner join users on users.ID_User=protocols.ID_User ';


DataModule1.FDQuery1.open;

Now, I can't figure a way to implement Add new entry, Update (entry-record), Delete (entry-record) . 现在,我没有办法实现添加新条目,更新(条目记录),删除(条目记录)的方法 Could someone show how to implement these events? 有人可以演示如何实施这些事件吗?

Your code snippets seem to show that you are not quite going about this the right way, because: 您的代码片段似乎表明您并没有以正确的方式进行此操作,因为:

a) You are using the same FDQuery for editing the user data as you are for populating ComboBox1. a)您正在使用与填充ComboBox1相同的FDQuery来编辑用户数据。

b) As all the columns in the Select in your Button2Click come from your protocols table, it is not clear why you think you need any of the Inner Joins. b)由于Button2Click中“选择”中的所有列都来自protocols表,因此尚不清楚为什么您认为需要任何内部联接。

c) You will find it much easier to debug and continue writing your app if you start giving your components meaningful names, rather than ComboBox1 , FDQuery1 , etc. c)如果您开始给组件赋予有意义的名称,而不是ComboBox1FDQuery1等,您将发现调试和继续编写应用程序要容易得多。

d) What you have asked in your q suggests that you may not be familiar with how Delphi datasets, including TFDQuery work, because if you were, you wouldn't be asking the question in the first place. d)您在q中询问的内容表明您可能不熟悉Delphi数据集(包括TFDQuery)的工作方式,因为如果您是这样,那么您根本就不会问这个问题。 I think you imagine that you have to implement code to perform your Inserts, Updates and Deletions. 我认为您想象您必须实现代码才能执行插入,更新和删除操作。 In fact, the functionality to do these operations is built into TFDQuery and other TDataSet descendants which work with SQ tables to do these operations automatically. 实际上,执行这些操作的功能内置于TFDQuery和其他TDataSet后代中,它们与SQ表一起使用以自动执行这些操作。 I'll explain how to do that below. 我将在下面说明如何执行此操作。

First try this 首先试试这个

  1. Rename your components like this 像这样重命名您的组件

    FDQuery1 -> qProtocols ComboBox1 -> cbxDepartmente Button4 -> btnOpenProtocols Button2 -> btnLoadDepartments FDQuery1-> qProtocols ComboBox1-> cbxDepartmente Button4-> btnOpenProtocols Button2-> btnLoadDepartments

  2. Add an extra TFDQuery to your datamodule and call it, say, qDepartmentList 向您的数据模块添加一个额外的TFDQuery并调用它,例如qDepartmentList

  3. Change your code as shown below. 如下所示更改代码。

Code: 码:

procedure TForm1.btnLoadDepartmentsClick(Sender: TObject);
begin
  // Re-written do avoid using "With ..."

  if DataModule1.qDepartmentList.Active then
    DataModule1.qDepartmentList.Close;

   DataModule1.qDepartmentList.Sql.Text := 'select distinct Department from protocols';
   DataModule1.qDepartmentList.Open;
  //  DataModule1.FDQuery1.First;  <_  You DON'T need First, because the call to Open does that

   cbxDepartmentList.Items.Clear;  // Clear the combo if it's already populated
   while  not DataModule1.qDepartmentList.Eof do begin
     // ComboBox1.Items.Create.Add(DataModule1.FDQuery1['Department']);
     //  You don't need ad should not call Create in the above

     cbxDepartmentList.Items.Add(DataModule1.qDepartmentList['Department']);
     DataModule1.qDepartmentList.Next;
   end;
end;

procedure TForm1.btnOpenProtocolsClick(Sender: TObject);
begin
  DataModule1.qProtocols.Sql.Text:= ' select protocols.ID_Document, protocols.Document, protocols.ID_Customer, protocols.Customer, protocols.Department, protocols.Date, protocols.Protocol, protocols.ID_Registrator, protocols.Registrator '
  + ' from protocols '
  + ' inner join documents on documents.ID_Document=protocols.ID_Document '
  + ' inner join registrators on registrators.ID_Registrator=protocols.ID_Registrator '
  + ' inner join customers on customers.ID_Customer=protocols.ID_Customer '
  + ' inner join users on users.ID_User=protocols.ID_User ';

  DataModule1.qProtocols.Open;
end;

At this point, pause and check that you can still compile your code OK. 此时,请暂停并检查您是否仍然可以编译代码。 Please not the comment I've added about "With" - with causes far more trouble than it is worth. 请不是我添加了关于“用”的评论- with原因远远更多的麻烦比它的价值。

Then: 然后:

  1. Add the following ButtonClick handlers: 添加以下ButtonClick处理程序:

    procedure TForm1.btnInsertClick(Sender: TObject); 过程TForm1.btnInsertClick(Sender:TObject); begin DataModule1.qProtocols.Insert; 开始DataModule1.qProtocols.Insert; end; 结束;

    procedure TForm1.btnSaveChangesClick(Sender: TObject); 过程TForm1.btnSaveChangesClick(Sender:TObject); begin DataModule1.qProtocols.Delete; 开始DataModule1.qProtocols.Delete; end; 结束;

    procedure TForm1.btnDeleteClick(Sender: TObject); 过程TForm1.btnDeleteClick(Sender:TObject); begin DataModule1.qProtocols.Delete; 开始DataModule1.qProtocols.Delete; end; 结束;

  2. Look in the online help what the Insert, Post and Delete methods of TDataSet do. 在联机帮助中查看TDataSet的Insert,Post和Delete方法的作用。

  3. At this point, we are nearly done. 至此,我们快完成了。 The only thing left to do is to handle moving the contents of the edit controls to and from qProtocols. 剩下要做的唯一事情就是处理将编辑控件的内容移入和移出qProtocols。 If you have used the db-aware verion of TEdit, namely TDBEDit, the DBEdits will do both operations automatically. 如果您使用了TEdit的可识别数据库的版本,即TDBEDit,则DBEdits将自动执行这两项操作。 If you have used TEdits - which is a mistake, in my opinion, you will need to copy the data from the Text properties of the TEdits, and also cbxDepartmentList into the qProtocols record's fields. 如果您使用过TEdits-我认为这是一个错误,您将需要将数据从TEdits的Text属性复制,还将cbxDepartmentList复制到qProtocols记录的字段中。 The best place to do that would probably be in the qProtocols AfterInsertEvent. 最好的选择可能是在qProtocols AfterInsertEvent中。

If you want me to add some code to use TEdits, I could, but you will save yourself a huge amount of time coding, debugging and maintaining your code if you use TDBEdits rather than TEdits, and TDBComboBox rather than TComboBox 如果您希望我添加一些代码来使用TEdit,可以,但是如果您使用TDBEdits而不是TEdits和TDBComboBox而不是TComboBox,则可以节省大量的代码编写,调试和维护代码的时间。

I'll leave it to you to study the online help to work how to implement a CancelChanges function. 我将留给您研究在线帮助,以研究如何实现CancelChanges功能。 Also, you may find it instructive to add a TDBNavigator to your form, connected to the same TDataSource as your DBGrid, because it shows how all the functionality of your TButtons, amd more, is wrapped up by it. 另外,您可能会发现将TDBNavigator添加到与DBGrid连接到同一TDataSource的窗体上很有启发性,因为它显示了TButton的所有功能以及更多功能。 As you'll see, it also automatically enables and disables certain of its speedbuttons depending on whether the dataset is being browsed or edited. 如您所见,它还会根据是浏览还是编辑数据集来自动启用和禁用某些速度按钮。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM