请教:运行中改变数据表对应的datasource的简便方法(200分)

  • 主题发起人 主题发起人 glink
  • 开始时间 开始时间
G

glink

Unregistered / Unconfirmed
GUEST, unregistred user!
我的程序需要用到20个数据表,我采取了只用一个table、一个datasource、一个pageControl控件来实现。我采用如下方法:
1。用table1.tablename:=***.db的办法修改table对应哪个.db数据表
2。在pageControl上使用20个页,在每个页上放置不同数据表需要用到的如 DBedit,DBmemo,DBgrid,
但是,我的麻烦是,在20个页上有100个左右的DBedit、DBmemo等,在程序运行中,在更换页的时候,同时需要更改不同DBedit、DBmemo对应的datasoure,(对应的field倒是可以在设计时进行设置),请教各位大侠,可不可以编个通用的procedure或function进行调用。
或者使用其他办法。
非常感谢。双手送上200两银子。
 
高!给个思路
设置访问表1的DBXXX的TAG为1,表2的为2……
for i:=0 to componentcount - 1do
begin
if components is TCustomcontrol then
begin
with components as tcustomcontroldo
begin
if tag = x then
datasource := x;
end;
end;
end;
 
datasource控件只有一个呀,glink,到底是怎样的?我不明白.
 
增加onChange事件。
procedure TForm1.PageControl1Change(Sender: TObject);
begin
case PageControl1.ActivePageIndex of
0:begin
Table1.Active:=false;
Table1.DatabaseName:='另名';
Table1.TableName :='库0.db';
Table1.Active:=true;
DataSource1.DataSet :=Table1;
DBGrid1.DataSource:=DataSource1;
end;
1:begin
Table1.Active:=false;
Table1.DatabaseName:='另名';
Table1.TableName :='库1.db';
Table1.Active:=true;
DataSource1.DataSet :=Table1;
DBGrid1.DataSource:=DataSource1;
end;
2:begin
Table1.Active:=false;
Table1.DatabaseName:='别名';
Table1.TableName :='库2.db';
Table1.Active:=true;
DataSource1.DataSet :=Table1;
DBGrid1.DataSource:=DataSource1;

end;
......
end;
end;
 
黄大侠功力不浅,在下佩服。
 
黄大侠:我就怕这样编程,如果这样则需要写20个CASE的情况,每个CASE要写10来行代码,才能使我的100个DBedit对应上相应的datasource。我想有没有简单的办法,如CJ大侠的,但是他的程序运行时在 if tag = x then
datasource :=xx;的时候会出现不能对只读的属性进行赋值。
CJ大侠,麻烦将你的程序再改一下,我水平有限。
谢谢各位朋友。
 
你不是只有一个TDataSource控件吗?设计时就可以设置好啊,不用运行时修改吧
 
同意ZH-SH,不过,我还是要分!好坏也有200啊……
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Db, DBTables, ExtCtrls, DBCtrls, Grids, DBGrids, ComCtrls;
type
TForm1 = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
DBGrid1: TDBGrid;
DBGrid2: TDBGrid;
DBNavigator1: TDBNavigator;
DBNavigator2: TDBNavigator;
Table1: TTable;
DataSource1: TDataSource;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure PageControl1Change(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
tblList:tstringlist;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
tblList := TStringList.Create;
tblList.Add('Country.db');
tblList.Add('Employee.db');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
tblList.Free;
end;

procedure TForm1.PageControl1Change(Sender: TObject);
var
i:Integer;
begin
ShowMessage(IntToStr(PageControl1.ActivePageIndex));
with Table1do
begin
if Active then
Close;
TableName := tblList[PageControl1.ActivePageIndex];
DataSource1.DataSet := Table1;//不知道你为什么要那么干,
//不过我还是把每个属性都
//给赋值一把,免得你说Readonly
end;
for i:=0 to ComponentCount - 1do
begin
if Components is TDBGrid then
with Components as TDBGriddo
if Tag = PageControl1.ActivePageIndex + 1 then
DataSource := DataSource1;
if Components is TDBNavigator then
with Components as TDBNavigatordo
if Tag = PageControl1.ActivePageIndex + 1 then
DataSource := DataSource1;
end;
Table1.Open;
end;

end.
 
DFM来了:
object Form1: TForm1
Left = 78
Top = 131
Width = 544
Height = 375
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 13
object PageControl1: TPageControl
Left = 0
Top = 0
Width = 536
Height = 348
ActivePage = TabSheet2
Align = alClient
TabOrder = 0
OnChange = PageControl1Change
object TabSheet1: TTabSheet
Caption = 'TabSheet1'
object DBGrid1: TDBGrid
Tag = 1
Left = 40
Top = 64
Width = 320
Height = 120
TabOrder = 0
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'MS Sans Serif'
TitleFont.Style = []
end
object DBNavigator2: TDBNavigator
Tag = 1
Left = 32
Top = 16
Width = 240
Height = 25
TabOrder = 1
end
end
object TabSheet2: TTabSheet
Caption = 'TabSheet2'
ImageIndex = 1
object DBGrid2: TDBGrid
Tag = 2
Left = 48
Top = 144
Width = 320
Height = 120
TabOrder = 0
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'MS Sans Serif'
TitleFont.Style = []
end
object DBNavigator1: TDBNavigator
Tag = 2
Left = 32
Top = 32
Width = 240
Height = 25
TabOrder = 1
end
end
end
object Table1: TTable
DatabaseName = 'DBDEMOS'
Left = 356
Top = 32
end
object DataSource1: TDataSource
DataSet = Table1
Left = 364
Top = 72
end
end
 
看看温柔一刀的专业水准的解答吧!
procedure SwapDataSource(wParent:TWincontrol;OldDS,NewDS:TDataSource);
var
i:Smallint;
begin
for i:= 0 to wParent.ControlCount-1do
if (GetPropInfo(wParent.Controls.ClassInfo, 'DataSource') = nil) then
continue
else
if GetObjectProp(wParent.Controls,'DataSource')<>nil then
if (GetObjectProp(wParent.Controls,'DataSource') as TDataSource).Name=OldDS.Name then
SetObjectProp(wParent.Controls, 'DataSource', NewDS);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
setDataSource(pagecontrol1.avtivetabsheet,datasource1,datasource2);
end;

各个参数我想很明白了,可以做到替换一个wincontrol下所有的
db control的datasource,这里的wParent设置为你当前活动的tabsheet,
我想正是你所需要的吧!
 
对不起,两个小失误:
1.忘了写 uses typinfo;
RTTI 的功能需要这个unit //delphi5
2.pagecontrol1.avtivetabsheet应为pagecontrol1.avtivepage
 
按照CJ的思路,根据我的要求对CJ的程序进行了如下修改,成功了!!!!
另外温柔一刀的程序,我看了一下,看不大懂,运行该程序,但delphi不认识GetObjectProp这个命令(delphi4),我也不知道如何修改。请温柔一刀继续赐教。
另外,有朋友问只有一个datasource,好象没必要换。如果没必要换,就不用这么麻烦了。比如aaaTDBedit指向datasource1,当你把datasource1从table1换到table2的时候,就会出现故障,因为对于aaaTDBedit来说,table2中没有table1对应的field。因此在不断对PageControl变换中,就不断地对如aaaTDBedit或bbbTDBedit所指向的datasource进行清空,再赋值,虽然赋值永远是datasource1,但若不清空,则总会出现指向错误。
希望我讲的你明白。
var
Form1: TForm1;
tblList:TStringlist;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
tblList := TStringList.Create;
tblList.Add('alarm.db');
tblList.Add('antenna.db');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
tblList.Free;
end;

procedure TForm1.PageControl1Change(Sender: TObject);
var i:Integer;
begin
with Table1do
begin
if Active then
Close;
TableName := tblList[PageControl1.ActivePage.pageIndex];
//table1.datasource永远指向datasource1,在设计时确定,不用更改。
end;
for i:=0 to ComponentCount-1do
begin
if Components is TDBGrid then
with Components as TDBGriddo
begin
dataSource:=DataSource2;
//指向一个空的DataSource2,相当于清空。不清空会出故障。
if Tag = PageControl1.ActivePage.pageIndex+1 then
DataSource := DataSource1;
end;
if Components is TDBedit then
with Components as TDBeditdo
begin
dataSource:=DataSource2;
if Tag = PageControl1.ActivePage.pageIndex+1 then
DataSource := DataSource1;
end;
//按照上面的if语句,可以替换使用 TDBcomboBox,TDBlisbox等等,
//这样就实现了各TDBcomboBox,TDBlisbox等datasource的动态改变。
end;
Table1.Open;
end;

end.
 
很遗憾,你用的D4,享受不到这最"爽"的方法了。
以后升级到D5的时候,别忘了再看看。
 
温同志的东西果然厉害啊……
 
过奖过奖,可惜英雄无用武之地,
如果以后有人用得着,我也就放心了。
另:to glink,你“成功”的程序中,
只要增加一种db control类型,就得增加一个if...
我的那段程序就是为了避免这个问题而作的,
使用的是RTTI的技术,可惜D4中没有GetObjectProp,
"功败垂成" :-)
 
后退
顶部