我建了两个数据库 A, B
数据库A : 有N个属性。其中一个属性‘AR’与 B 数据库的记录相关联。
数据库B : 有两个属性。‘Br1’属性的中文名,‘Br2’属性的数字编号。数据库A 已经与DBGrid1 相关联。
我希望能完成以下功能:
1. 点击DBGrid1 即 数据库A任一记录的‘AR’属性的时候,能以下拉菜单的方式显示 数据库B的所有记录的‘Br1’属性。
2. 当在下拉菜单中选中一项记录的时候,能够向数据库A中录入 数据库B选中记录的‘Br2’属性。不知道我说清楚没有,请各位高手指点一下。我是新学Delphi 就碰到工程了,请详细说明一下并给出详细代码,谢谢!!!
数据库A : 有N个属性。其中一个属性‘AR’与 B 数据库的记录相关联。
数据库B : 有两个属性。‘Br1’属性的中文名,‘Br2’属性的数字编号。数据库A 已经与DBGrid1 相关联。
我希望能完成以下功能:
1. 点击DBGrid1 即 数据库A任一记录的‘AR’属性的时候,能以下拉菜单的方式显示 数据库B的所有记录的‘Br1’属性。
2. 当在下拉菜单中选中一项记录的时候,能够向数据库A中录入 数据库B选中记录的‘Br2’属性。不知道我说清楚没有,请各位高手指点一下。我是新学Delphi 就碰到工程了,请详细说明一下并给出详细代码,谢谢!!!
或者使用AdvStringGrid.自己写代码实现
Samland(samland)
我听别人说DBGrid好像能完成这个功能。
我是新学的delphi 要自己写,可能写不出来哟!
在dbgird的DBGrid1EditButtonClick事件中创建该窗体
在窗体show事件中可以通过adoquery加载需要显示的信息(从b库中查询获得放在listbox或dbgird中)
在确定的click事件中保存该信息就可以了。不知你是否了解。
实际上是数据表A,数据表B吧,
其实你的要求很容易实现,在数据集(table,query)里,
新建一个lookup字段:lookup字段的使用
在实际的数据库程序中,我们经常使用编码表,例如对消费品名进行编码,在存入消费库中时使用消费品编码,而在使用DBGRID或其他数据明了构件显示出来时使用具体内容。这就要使用lookup字段了。 我们可以作以下试验:
(1)新建一个项目,使用database desktop建两个库,别名test,如下:
nameid:编码表字段名 Name Id
记录1 Tanglu 1
记录2 shangwang 2 id:欲存入表(现为空)字段名 Id
记录1
记录2
在Form1上放如下构件:table1 指向nameid表,即databasename=test; tablename=nameid;
Datasource1 指向table1,即dataset=table1
table2 指向id表,即databasename=test; tablename=id;
Datasource2 指向table2,即dataset=table2
dbgrid1 指向table2,即dataSource=dataSource2
(2)双击table2,弹出字段编辑器,在字段编辑器上右击,选择“addfields...",加入“id"字段;再选择“newfield..."。这时弹出newfield对话框,如下填写:name type Field type Key fields dataset Lookup keys Result field
test string ookup Id Table1 id name
(3)将table1和table2的active属性置为true,编译运行。
这时可以看出,从test字段下拉出姓名,选定一个后,存入id字段的是其编码,这样就达到了目的。
用第三方控件很容易实现,如Inforpower或者是rx都有控件提供
PRec = ^TRec;
TRec = record
Br1: String;
Br2: Integer;
end;然后定义一个TComboBox的全局变量cbRec
var
cbRec: TComboBox;然后定义个cbRec的onChange事件;
procedure TForm1.MyChange(Sender: TObject);
var
Rec: PRec;
begin
Rec := PRec(cbRec.Items.Objects[cbRec.ItemIndex]);
//就可以得到Rec^.Br1, Rec^.Br2,然后更新数据库A
……
end;然后再FormCreate事件中初始化这个ComboBox,并查询出数据库B中的记录建立Items;
var
Rec: PRec;
begin
cbRec := TComboBox.Create(nil);
……此处为查询过程……
while Query.Eof do
begin
New(PRec);
Rec^.Br1 := Query.FieldByName['Br1'].AsString;
Rec^.Br2 := Query.FieldByName['Br2'].AsInteger;
cbRec.Items.AddObject(Rec^.Br1, TObject(Rec));
Query.Next;
end;
cbRec.OnChange := MyChange;
end;最后在DBGrid1的Edit事件里重画当前Cell为cbRec,关键就得到当前Cell的Rect,然后设置cbRec的Rect为Cell的Rect!然后设置cbRec的Visible为True,就用一个下拉列表覆盖了当前的Cell了!
zhangheaaa(竹) 先谢了!
我作到你的(2)步了:
再选择“newfield..."。这时弹出newfield对话框,如下
我没找到 "newfield.." 这个选择项,是怎么回事,
我用的是delphi 6
1.在你的query里建一个lookup字段,这个lookup字段指向你的那个代码字段A.AR,另外三个属性好像是关联到第二个query的,记不得名字了
2.在DBgrid中,你要显示汉字和编辑下拉框的那一列的field就选择这个新建的lookup字段就好了
我照你们说的作出来了,谢谢!!!不过还有点问题,还想请教一下T各位高手:我的‘AR’是数值型
‘Br1’是数值型
‘Br2’是文本类型要求: 1. 点击‘AR’的时候显示‘Br2’。
2. 选中的时候‘AR’内输入的是‘Br1’。还有,我选中了之后为什么不能输入到‘AR’里,我试了多次也不行,请问是怎么回事?
begin
if trim(yhm.Text)='' then
begin
messagebox(handle,'用户名称不能为空!','提示',mb_ok+mb_iconerror);
yhm.SetFocus;
exit;
end;
adoquery2.Close;
adoquery2.SQL.Clear;
adoquery2.SQL.Add('select * from xt00');
adoquery2.SQL.Add('where');
adoquery2.SQL.Add('t12='''+trim(yhm.Text)+'''');
adoquery2.Open;
if trim(edit1.Text)<>adoquery2.FieldByName('t14').AsString then
begin
messagebox(0,'通行密码错误!','提示',16);
edit1.SetFocus;
exit;
end
else
begin
loginform.Close;
end;
end;
procedure Tloginform.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
var
i,j:integer;
begin
with adoquery2 do begin
Close;
SQL.Clear;
SQL.Add('select * from xt00 where t12=:a');
Parameters[0].Value:=yhm.Text;
Open;
end;
for i:=0 to mainform.MainMenu.Items.Count-3 do begin
for j:=0 to mainform.MainMenu.Items[i].Count-1 do begin
if pos(midstr(mainform.MainMenu.Items[i].Items[j].Name,2,4),adoquery2.fieldbyname('t15').asstring)<>0 then begin
mainform.MainMenu.Items[i].Items[j].Enabled:=true;
end else begin
mainform.MainMenu.Items[i].Items[j].Enabled:=false;
end;
end;
end;
adoquery2.Open;
mainform.StatusBar1.Panels[3].Text:=yhm.Text;
end;