用dxDBGrid控件来做数据录入,要同时显示多表的数据,又要能追加记录,该采用什么方法来实现?(200)

  • 主题发起人 主题发起人 delphi002
  • 开始时间 开始时间
D

delphi002

Unregistered / Unconfirmed
GUEST, unregistred user!
有两个表表Goods(物品清单)的字段为: Autoid integer identity(1,1) Primary Key, GoodsName Varchar(30),//物品名称 Unit Varchar(10), TotalNum Integer, Memo Varchar(100))表StockBill(采购申请单) Autoid integer identity(1,1) Primary Key, BillNo Varchar(50), GoodsId Integer,(对应于Goods的Autoid值) BillNum Integer, OperateDate DateTime, Memo Varchar(100))现在设计一个Form,用以输入采购申请单,用dxDBGrid控件来作录入界面,当改变GoodsId的值时,显示出来GoodsName及Unit,这该如何设计?我刚开始想到的方法是在ADOQuery控件中添加查询字段来实现,但如果Goods表的记录太多的话,会不会影响速度呢?
 
请查看一下UpdateSQL1有关的资料。-----------当改变GoodsId的值时,显示出来GoodsName及Unit,这该如何设计?-->在绑定DataSet的datasource的OnDataChange事件中处理,如果当前DataSet是编辑状态,且变化的字段是GoodsId,则编辑GoodsName及Unit字段的值。
 
to znxia不好意思,我要编辑的是StockBill表(该表是没有GoodsName,Unit等字段),但在编辑该表的记录时,我要同时显示出StockBill表GoodsId所对应的GoodsName,Unit等值(这通过StockBill表的GoodsId与Goods表的Autoid相匹配),所以你的方法不能解决问题.我目前采用的是在adoquery1(select * from stockbill where atuoid=0)中添加查询字段来解决,但添加查询字段的问题是,必须有另一个ADOQUERY2来查询Goods表,在FORM打开时就OPEN ADOQUERY2,这样的话,如果Goods的记录很大的话,那在打开FORM时会不会需要较长时间?或者在录入的时间会不会影响录入速度?
 
我的意思是用一个UpdateSQL1,里面的sql是select a.*, b.GoodsName, b.unitfrom StockBill a, Goods bwhere a.GoodsId = b.autoid这样数据显示很直观,至于界面上怎么编辑,我不必多说。另:你应该还没有查看UpdateSQL1有关的资料。它可以只更新其中的一个表。
 
to znxia关于你所提到的UpdateSQL1的资料,说实话,我是还没看过.等下有空找找看.先谢谢了.
 
to znxia你所说的UPDATESQL1的资料,我看了一下,由于我现在使用的是ADO控件,如果要改成BDE的话,会比较麻烦.而且我感觉BDE连接SQL SERVER数据库较麻烦.
 
嗯,那就采用ClientDataSet来查询数据。界面上放置3个控件,其中ClientDataSet1用于和界面上控件绑定。如下: object ADOQuery1: TADOQuery Parameters = <> end object DataSetProvider1: TDataSetProvider DataSet = ADOQuery1 end object ClientDataSet1: TClientDataSet Aggregates = <> Params = <> ProviderName = 'DataSetProvider1' end在ClientDataSet1的AfterPost和AfterDelete中处理后台数据的更新(新增、修改、删除)。处理完成后,调用一下函数ClientDataSet1.MergeChangeLog,将log内容清除。
 
to znxia我按你的思路去想过,但我的ADOQuery1的SQL 语句应该如何写呢?是下面这样写吗?select a.*, b.GoodsName, b.unitfrom StockBill a, Goods bwhere a.GoodsId = b.autoid由于我用的是dxDBGrid1作录入控件,dxDBGrid1.DataSource =DataSource1,而DataSource1的DataSet是ClientDataSet1吗?,我想了很久都不清楚如何做,还请你帮忙!
 
建立了2个测试表,和你的类似,但没有memo字段。测试通过。记得给分。dfm文件:object Form1: TForm1 Left = 119 Top = 176 Width = 720 Height = 500 Caption = 'Form1' Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] OldCreateOrder = False PixelsPerInch = 96 TextHeight = 13 object DBGrid1: TDBGrid Left = 24 Top = 40 Width = 521 Height = 345 DataSource = DataSource1 TabOrder = 0 TitleFont.Charset = DEFAULT_CHARSET TitleFont.Color = clWindowText TitleFont.Height = -11 TitleFont.Name = 'MS Sans Serif' TitleFont.Style = [] end object BtnOpen: TButton Left = 576 Top = 56 Width = 75 Height = 25 Caption = '&acute;ò&iquest;&ordf;&Ecirc;&yacute;&frac34;&Yacute;&frac14;&macr;' TabOrder = 1 OnClick = BtnOpenClick end object DataSource1: TDataSource DataSet = ClientDataSet1 Left = 176 Top = 224 end object ClientDataSet1: TClientDataSet Aggregates = <> Params = <> ProviderName = 'DataSetProvider1' BeforePost = ClientDataSet1BeforePost AfterPost = ClientDataSet1AfterPost BeforeDelete = ClientDataSet1BeforeDelete AfterDelete = ClientDataSet1AfterDelete Left = 120 Top = 240 end object DataSetProvider1: TDataSetProvider DataSet = ADOQuery1 Options = [poAllowCommandText] Left = 120 Top = 280 end object ADOQuery1: TADOQuery Connection = ADOConnection1 Parameters = <> Left = 128 Top = 336 end object ADOConnection1: TADOConnection ConnectionString = 'Provider=MSDASQL.1;Password="";Persist Security Info=True;Data S' + 'ource=Acctest' LoginPrompt = False Provider = 'MSDASQL.1' Left = 176 Top = 336 end object ADOCommand1: TADOCommand Connection = ADOConnection1 Parameters = <> Left = 176 Top = 392 endend--------------------------------------pas 文件:unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, DB, ADODB, Provider, DBClient, Grids, DBGrids;type TForm1 = class(TForm) DBGrid1: TDBGrid; DataSource1: TDataSource; ClientDataSet1: TClientDataSet; DataSetProvider1: TDataSetProvider; ADOQuery1: TADOQuery; ADOConnection1: TADOConnection; BtnOpen: TButton; ADOCommand1: TADOCommand; procedure ClientDataSet1AfterPost(DataSet: TDataSet); procedure ClientDataSet1BeforeDelete(DataSet: TDataSet); procedure BtnOpenClick(Sender: TObject); procedure ClientDataSet1AfterDelete(DataSet: TDataSet); procedure ClientDataSet1BeforePost(DataSet: TDataSet); private { Private declarations } FStatusFilter:TUpdateStatus; procedure DoInsert; procedure DoUpdate; public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}procedure TForm1.ClientDataSet1BeforePost(DataSet: TDataSet);begin IF ClientDataSet1.State=dsInsert then FStatusFilter:=usInserted else FStatusFilter:=usModified;end;procedure TForm1.ClientDataSet1AfterPost(DataSet: TDataSet);begin if FStatusFilter=usInserted then //&sup2;é&iquest;&acute;&micro;±&Ccedil;°&frac14;&Ccedil;&Acirc;&frac14;&Ecirc;&Ccedil;&ETH;&Acirc;&Ocirc;&ouml;/&ETH;&THORN;&cedil;&Auml;&ordm;ó&micro;&Auml;&Ecirc;&yacute;&frac34;&Yacute; DoInsert else if FStatusFilter=usModified then DoUpdate; ClientDataSet1.MergeChangeLog;end;procedure TForm1.ClientDataSet1BeforeDelete(DataSet: TDataSet);begin ADOCommand1.CommandText:=format('Delete from StockBill where Autoid=%d ',[ClientDataSet1.FieldByName('Autoid').AsInteger] ); ADOCommand1.Execute;end;procedure TForm1.ClientDataSet1AfterDelete(DataSet: TDataSet);begin ClientDataSet1.MergeChangeLog; //&Ccedil;&aring;&sup3;&yacute;&Egrave;&Otilde;&Ouml;&frac34;end;procedure TForm1.BtnOpenClick(Sender: TObject);begin ClientDataSet1.Close; ClientDataSet1.CommandText:=' select a.*, b.GoodsName, b.unit '+ 'from StockBill a, Goods b '+ 'where a.GoodsId = b.autoid '; ClientDataSet1.Open;end;procedure TForm1.DoInsert;var S:String;begin S:=Format('Insert into StockBill values (%d, ''%s'', %d, %d, #%s#) ', [ClientDataSet1.FieldByName('Autoid').AsInteger, ClientDataSet1.FieldByName('BillNo').AsString, ClientDataSet1.FieldByName('GoodsId').AsInteger, ClientDataSet1.FieldByName('BillNum').AsInteger, ClientDataSet1.FieldByName('OperateDate').AsString ]); ADOCommand1.CommandText:=S; ADOCommand1.Execute;end;procedure TForm1.DoUpdate;var S:String;begin S:=Format('Update StockBill '+ 'Set BillNo=''%s'', '+ ' GoodsId=%d, '+ ' BillNum=%d, '+ ' OperateDate= #%s# '+ 'Where Autoid=%d ', [ClientDataSet1.FieldByName('BillNo').AsString, ClientDataSet1.FieldByName('GoodsId').AsInteger, ClientDataSet1.FieldByName('BillNum').AsInteger, ClientDataSet1.FieldByName('OperateDate').AsString, ClientDataSet1.FieldByName('Autoid').AsInteger ]); ADOCommand1.CommandText:=S; ADOCommand1.Execute;end;end.
 
to znxia 实在不好意思,我用你的代码测试了一下,目前已基本上解决了问题,现在的问题是,假如我修改了GoodsId,不会及时的刷新GoodsName值,不会是要执行ClientDataSet1.Active :=False;ClientDataSet1.Active :=TRue;这两行吧? 如果这个问题解决了的话,该贴就得结贴了,还请您帮忙!
 
当然不需要。设置DataSource.OnDataChange事件如下:procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);begin if Field=nil then exit; if not(ClientDataSet1.State in dsEditModes) then exit; if Field<>ClientDataSet1.FieldByName('GoodsId') then Exit; //通过另外一个ADOQuery,根据GoodsId字段的值,获得 GoodsName和unit,并将该数据赋值给 ClientDataSet1的对应字段。 ADOQuery2.Close; ADOQuery2.sql.text:= 'Select GoodsName, unit from Goods where autoid= '+IntToStr(ClientDataSet1.FieldByName('GoodsId').AsInteger); ADOQuery2.Open; ClientDataSet1.FieldByName('GoodsName').AsString:= ADOQuery2.FieldByName('GoodsName').AsString; ClientDataSet1.FieldByName('unit').AsString:= ADOQuery2.FieldByName('unit').AsString; ADOQuery2.Close;end;
 
非常感谢您的多次帮忙,谢谢了!
 
后退
顶部