高分求解请教个delphi三层问题:
在三层里用Clientdataset ,DBGrid ,多个Edit(用于添加多个明细)三控件,
想把多个Edit的数据暂时缓存到Clientdataset里,然后在DBGrid里显示出来,DBGrid显示一行说明添加了一条明细,显示多行说明添加了多条明细,问题出来了,DBGrid 只接受一条明细,下一次向DBGrid添加明细时,上一次添加的明细就会被本次输入的明细覆盖掉,也就是说实际只能接受一条细,为什么只能往DBGrid里输入一条明细呢?Clientdataset不可能只缓存一条记录的啊?怎么会这样?请高手支招啊....部分代码如下:
with DM_Frm.ClientDataSet4 do
begin
DBGrid1.DataSource:=DataSource1;
close;
commandtext:='select * from materialstable';
open;
Append;
FieldByName('原料编号').Value:=Edit6.Text;
FieldByName('原料名称').Value:=Edit17.Text;
FieldByName('规格').Value:=Edit18.Text;
FieldByName('实收数').Value:=Edit7.Text;
FieldByName('送验数').Value:=Edit15.Text;
FieldByName('件数').Value:=Edit19.Text;
FieldByName('凭单号').Value:=Edit16.Text;
FieldByName('备注').Value:=Edit20.Text;
post;
end;
在三层里用Clientdataset ,DBGrid ,多个Edit(用于添加多个明细)三控件,
想把多个Edit的数据暂时缓存到Clientdataset里,然后在DBGrid里显示出来,DBGrid显示一行说明添加了一条明细,显示多行说明添加了多条明细,问题出来了,DBGrid 只接受一条明细,下一次向DBGrid添加明细时,上一次添加的明细就会被本次输入的明细覆盖掉,也就是说实际只能接受一条细,为什么只能往DBGrid里输入一条明细呢?Clientdataset不可能只缓存一条记录的啊?怎么会这样?请高手支招啊....部分代码如下:
with DM_Frm.ClientDataSet4 do
begin
DBGrid1.DataSource:=DataSource1;
close;
commandtext:='select * from materialstable';
open;
Append;
FieldByName('原料编号').Value:=Edit6.Text;
FieldByName('原料名称').Value:=Edit17.Text;
FieldByName('规格').Value:=Edit18.Text;
FieldByName('实收数').Value:=Edit7.Text;
FieldByName('送验数').Value:=Edit15.Text;
FieldByName('件数').Value:=Edit19.Text;
FieldByName('凭单号').Value:=Edit16.Text;
FieldByName('备注').Value:=Edit20.Text;
post;
end;
解决方案 »
- 如何隐藏其他窗体在任务栏上的窗口
- 把一个登录对话框做成dll,一旦连接数据库后,再关闭就无响应了
- 如何确定两个程序间用何种进程间通讯
- 一个很奇怪的问题,有钱的捧钱场,没钱的捧人场!
- 如何在B程序中获取A程序中的某些内容(如StringGrid中)
- 在Service Application里加入ADOConnect,为什么在TService的OnStart事件里做ADOConnect.Connect:=true 启动时会出错?(编译无错)
- 如何构筑一个前端能被.Net,Delphi等共用的数据库Web Services
- 关于treeview的问题?
- 使用ListView控件时,点击图标会出现很大一个选择框,请问如何才能去掉?
- 我想来这里的人都是想互相学习的人,为什么要排斥弱者。
- 一个关于标签式窗体的问题!
- RO保存文件到Oracle的Blob字段问题(来人接分)~
建议在服务器中专门写一个更新数据的程序(代码),每次更新就调用它。
TO disburden
我的DataSource1的dataset指向DM_Frm.ClientDataSet4
procedure TBase_Frm1.Button1Exit(Sender: TObject);
begin
inherited;
DM_Frm.SocketConnection1.APPServer.BeginTran;
Try
DBGrid1.DataSource:=DataSource1;
DataSource1.DataSet:=DM_Frm.ClientDataSet5;
with DM_Frm.ClientDataSet5 do
begin close;
commandtext:='select * from materialstable';
open;
Append;
FieldByName('原料编号').Value:=trim(Edit1.Text);
FieldByName('原料名称').Value:=trim(Edit2.Text);
POST;
//ApplyUpdates(0);
end;
Except
DM_Frm.SocketConnection1.APPServer.RollBackTran;
ShowMessage('保存失败!');
exit;
End;
DM_Frm.SocketConnection1.APPServer.CommitTran;
end;
如上所示:我的用意是想通过post提交,在感知控件DBGrid里能显示出来,用本地Clientdataset缓存多条明细,然后通过ApplyUpdates(0)来提交在Clientdataset里的多条明细到数据库...
这样的话,就只有Clientdataset缓存到本地,而不要用到数据库的时时表来存数据!因为考虑到两个用户同时保存明细到临时明细表的话,第一个提交明细时会看到第二个用户保存在临时明细表里的明细,如果第一个用户提交临时明细表数据到正式明细表时,会把第二个用户存在临时明细表里的数据一并提交,导致出错
procedure TBase_Frm1.Button1Exit(Sender: TObject);
begin
inherited;
DM_Frm.SocketConnection1.APPServer.BeginTran;
Try
DBGrid1.DataSource:=DataSource1;
DataSource1.DataSet:=DM_Frm.ClientDataSet5;
with DM_Frm.ClientDataSet5 do
begin close;
commandtext:='select * from materialstable';
open;
Append;
FieldByName('原料编号').Value:=trim(Edit1.Text);
FieldByName('原料名称').Value:=trim(Edit2.Text);
POST;
//ApplyUpdates(0);
end;
Except
DM_Frm.SocketConnection1.APPServer.RollBackTran;
ShowMessage('保存失败!');
exit;
End;
DM_Frm.SocketConnection1.APPServer.CommitTran;
end;
如上所示:我的用意是想通过post提交,在感知控件DBGrid里能显示出来,用本地Clientdataset缓存多条明细,然后通过ApplyUpdates(0)来提交在Clientdataset里的多条明细到数据库...
这样的话,就只有Clientdataset缓存到本地,而不要用到数据库的时时表来存数据!因为考虑到两个用户同时保存明细到临时明细表的话,第一个提交明细时会看到第二个用户保存在临时明细表里的明细,如果第一个用户提交临时明细表数据到正式明细表时,会把第二个用户存在临时明细表里的数据一并提交,导致出错
不要使用ApplyUpdates(0)来提交在Clientdataset里的多条明细到数据库...,这很不可靠在。
因此,建议你对于加入数据(行),采取二步:
1、向ClientDataSet(即DBGrid)中加入数据行;
2、向服务器端加入数据。
我的代码,仅供参考: SQL:='INSERT INTO 成品调料采购 (单位,数量,金额,ID) VALUES('+
#39+Edit1.Text+#39+','+
#39+ComboBox1.Text+#39+','+
#39+ComboBox2.Text+#39+','+
#39+ID+#39+')';
if DataModule1.SocketConnection1.AppServer.MyQuery(sql,err)
then begin
DataModule1.ClientDataSet1.Append;
DataModule1.ClientDataSet1.Fields.FieldByName('单位').AsString:=Edit1.Text;
DataModule1.ClientDataSet1.Fields.FieldByName('数量').AsString:=ComboBox1.Text;
DataModule1.ClientDataSet1.Fields.FieldByName('金额').AsString:=ComboBox2.Text;
DataModule1.ClientDataSet1.Fields.FieldByName('ID').AsString:=ID;
DataModule1.ClientDataSet1.post;
DBGrid_AutoSize(DBGrid1,DataModule1.DataSource1);
end
else MessageBox(self.handle,pchar('插入数据出错:'+err),'错误',MB_OK+MB_ICONERROR);
DataModule1.SocketConnection1.AppServer.MyQuery(sql,err)
就是调用服务器端的保存数据方法。一但远程调用成功,就在本地ClientDataSet中加入数据。使用二步的方式,非常可靠稳定。
ClientDataSet指向DBGrid [DBGrid1.DataSource:=DataSource1;
DataSource1.DataSet:=DM_Frm.ClientDataSet5;]是不是这样实现?
第二步提交缓存数据到数据库倒是可以实现
DBGrid.datasource指向datasource1,datasource1 指向 clientdataset4 ,向Clientdataset缓存多条数据,在感知控件DBGrid里能显示出来多条数据,这一想法 是不是可行?
二、在客户端,分二步(1)向服务器传输数据(2)对本地的ClientDataSet,实质上就是DBGrid的数据集,相应处理。
DataModule1.ClientDataSet1.Fields.FieldByName('单位').AsString:=Edit1.Text;
DataModule1.ClientDataSet1.Fields.FieldByName('数量').AsString:=ComboBox1.Text;
DataModule1.ClientDataSet1.Fields.FieldByName('金额').AsString:=ComboBox2.Text;
DataModule1.ClientDataSet1.Fields.FieldByName('ID').AsString:=ID;
DataModule1.ClientDataSet1.post;
2、运程调用传输数据 调用服务器中的方法:MyQuery(sql,err)
if DataModule1.SocketConnection1.AppServer.MyQuery(sql,err) then
begin
...
end;
本地的dbgrid是一定和本地clientdataset关联的。本地clientdataset数据操作不会直接写入到数据库的。但写入本地是为了在DBGrid中显示数据。
谢谢bluesukeke,是不应该CLOSE,否则保存不了数据到clientdataset
谢谢所有跟贴的各位,
谢谢lyhoo163,很热心的一位兄弟!