调用公共单元某个过程的问题!在线关注!应该怎样做呢?具体的见内容!
我的系统中新建了一个单元文件proc,单元文件里放着一些公共的过程或函数。代码是:
我想实现是把数据库中的一个表的某个字段的所有内容都添加到 listbox中。但是我不知道在其他单元应该如何调用这个过程?我的这个简单的代码有什么错误,希望得到指点!
我做的有哪些地方不妥呢?
unit proc;
interface
uses
Windows, Messages, SysUtils, DB, Variants, Classes, StdCtrls;
implementation
procedure listadd(Name1:TListBox;Name2:TDataSet;str:string);
var i:integer;
begin
for i:=0 to Name2.RecordCount-1 do
Try
//将所某数据集中的某字段添加到listbox中
Name1.Items[i]:=Name2.fieldbyname(str).AsString;
Name2.Next;
except
Name2.Close;
end;
end;
end.
在其他单元的type中用不用写procedure listadd(Name1:TListBox;Name2:TDataSet;str:string);呢?调用中还应该注意些什么呢?在其他单元中我是这样调用的:
implementation
uses DM,datasub,proc;
{$R *.dfm}
procedure Tfrm_data.ComboBox1Click(Sender: TObject);
var i:integer;
begin
btnappend.Enabled:=true;
if combobox1.Text='区域' then
begin
listbox1.Items.Clear;
btnrework.Enabled:=false;
btndelete.Enabled:=false;
with adoquery1 do
begin
close;
sql.Clear;
sql.Add(s+'area');
open;
end; //end with
listadd(listbox1,adoquery1,name);《-----在这里调用,但是总是不对!
而且在type中没有procedure listadd(Name1:TListBox;Name2:TDataSet;str:string);
提示如下:
[Error] data.pas(71): Undeclared identifier: 'listadd'
[Fatal Error] KHGL.dpr(13): Could not compile used unit 'data.pas'
问题点数:60、回复次数:21Top
1 楼codeli(新手)回复于 2004-09-01 08:38:58 得分 0
希望得到大家的指点!各位上班了吗?Top
2 楼weizi2000(秋风啊)回复于 2004-09-01 08:58:03 得分 20
先声明一下:
uses
Windows, Messages, SysUtils, DB, Variants, Classes, StdCtrls;
procedure listadd(Name1:TListBox;Name2:TDataSet;str:string); {这里加一句}
implementation
...
Top
3 楼meiqingsong(阿飛)回复于 2004-09-01 08:58:40 得分 0
在proc的interface 下
声明 procedure Tfrm_data.ComboBox1Click(Sender: TObject);Top
4 楼codeli(新手)回复于 2004-09-01 09:03:37 得分 0
我试一下!
Top
5 楼luke5678()回复于 2004-09-01 09:04:23 得分 5
对,在接口interface下声明一下,在其它单元里记得引用一下这个公共单元就可以了Top
6 楼savagexyz(狼雨)回复于 2004-09-01 09:06:11 得分 0
声明问题,函数和过程使用之前必须声明
[Error] data.pas(71): Undeclared identifier: 'listadd'
这是提示listadd没有声明,
Top
7 楼dyzg(地藏)回复于 2004-09-01 09:08:18 得分 5
对,要先声明一下的。Top
8 楼codeli(新手)回复于 2004-09-01 09:10:35 得分 0
weizi2000(秋风啊-秋的叹息)我试了编译也通过了!可是运行时提示有错!
meiqingsong(阿飛)你说的意思就是把procedure Tfrm_data.ComboBox1Click(Sender: TObject);写到interface下面吗?
Top
9 楼codeli(新手)回复于 2004-09-01 09:18:54 得分 0
声明的那个问题解决了!可是在调用这个过程后提示这样一个错误:
project khgl.exe raised exception class EDatabaseError with message 'ADOQuery:field'frm_data' not found' process stoped. Use Step or Run to continue.Top
10 楼weizi2000(秋风啊)回复于 2004-09-01 09:23:31 得分 0
那时Top
11 楼weizi2000(秋风啊)回复于 2004-09-01 09:24:46 得分 5
呵呵,碰到了回车键;那时你传入的ADOQuery中没有frm_data数据字段,查一下看看Top
12 楼codeli(新手)回复于 2004-09-01 09:26:08 得分 0
各位都上哪儿去了?怎么没有回复了呢?我是新手,有些地方让大家见笑了!Top
13 楼codeli(新手)回复于 2004-09-01 09:33:12 得分 0
还有什么地方需要注意的呢?点拨一下小弟吧!weizi2000(秋风啊-秋的叹息) :那时你传入的ADOQuery中没有frm_data数据字段〈------这句不太理解,帮忙解释一下吧!:)Top
14 楼codeli(新手)回复于 2004-09-01 09:35:42 得分 0
luke5678(奇异)我一定会注意的,谢谢!Top
15 楼weizi2000(秋风啊)回复于 2004-09-01 09:38:43 得分 0
message 'ADOQuery:field'frm_data' not found' 其意为你用到的ADOQuery中用到了一个叫frm_data的字段,可是这个字段在ADOQuery中没有找到,也就是你的select中没有它,再检查一下Top
16 楼asj(破喉咙)回复于 2004-09-01 09:40:30 得分 20
声明应该按照weizi2000(秋风啊-秋的叹息)的方式来
运行时错误是因为这一句:
Name1.Items[i]:=Name2.fieldbyname(str).AsString;
记录数目超过你的Items的个数就会出错,改成这样:
Name1.Items.Clear;
for ...
Name1.Items.Add(Name2.fieldbyname(str).AsString);
下面的都是建议:
参数名字起的不好,为什么叫Name1,Name2,不怕自己晕?
procedure listadd(ListBox:TListBox;DataSet:TDataSet;FieldName:string);
一般循环数据库是这样写的
while not DataSet.Eof do
...
不用RecordCount的原因是,有些数据库已某种游标方式打开的时候可能得不到这个值,或者得到错误的值,此外获得这个值也可能很耗时。
try...except不要把异常吞掉,否则在运行时出错你都看不到错误是什么,一般这样
except
//处理错误
raise; //再次引发异常,让外层的错误处理捕获;
或者
on E:Exception do
ShowMessage('发生错误:' + E.Message);
end;
此外你的错误处理有问题,在循环中出错就关掉DataSet,但是循环还在继续,那么下次循环的时候就会因为读取关闭了的DataSet上的数据引发异常,完全没有起到异常保护的作用,反倒让人搞不清出了什么问题。建议这样改动。
try
for ...
begin
end;
except
DataSet.Close;
end;
不过这样还是有个问题,DataSet是在过程外打开的,但却在过程里关闭,这是不合适的做法。请记住关于资源管理的一个原则:
谁创建,谁释放;在哪里创建,在哪里释放。
此外,出错了关闭,没出错的时候又是什么时候又谁来关闭呢?
其实归根结底是:为什么出错的时候要关闭DataSet?要完全解决这个问题,请仔细考虑你的错误处理究竟要起到什么作用。
另外,一般这种函数会这样写:
procedure GetFieldStrs(List: TStrings; DataSet: TDataSet; FieldName: string);
调用的时候传入ListBox.Items,这样的好处是只要需要获取字段值的列表,都可以采用这个函数,比如你不再向ListBox中加入值,而是放到ComboBox中,那么只需要传入ComboBox.Items就可以了,而原来的写法必须修改参数的类型。
Top
17 楼codeli(新手)回复于 2004-09-01 09:43:02 得分 0
搞定了,谢谢各位了!马上结帖了!各位能留个联系方式吗?如果你们没有来这里,我也好有地方请教各位啊!Top
18 楼asj(破喉咙)回复于 2004-09-01 09:46:02 得分 5
那时你传入的ADOQuery中没有frm_data数据字段
你调用的语句是这样写的:
listadd(listbox1,adoquery1,name);
同志,你的Name是在哪里声明和赋值的?现在这样是把Self.Name传入也就是窗口的名字,所以是frm_Data,这个是你的本意么?照我的理解,你是想传入字段名字吧。
Top
19 楼codeli(新手)回复于 2004-09-01 09:57:43 得分 0
谢谢你asj() 能有你们这些朋友的关心,我深感荣幸啊!Top
20 楼codeli(新手)回复于 2004-09-01 09:59:19 得分 0
我把其中的name 改成'name'后就没有问题了!是的,你说对了,我是想传如字段名的。Top
21 楼codeli(新手)回复于 2004-09-01 10:01:42 得分 0
unit proc;
interface
uses
Windows, Messages, SysUtils, DB, Variants, Classes, StdCtrls;
procedure listadd(Name1:TListBox;Name2:TDataSet;str:string);
implementation
暂时上面的是对了,但是什么时候才用到
type procedure listadd(Name1:TListBox;Name2:TDataSet;str:string);呢???
Top




