谁能帮我捕获通过DBGrid编辑ADOquery的异常信息!300分 (300分)

  • 主题发起人 主题发起人 电脑农民
  • 开始时间 开始时间
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnException := AppException;
end;

procedure TForm1.AppException(Sender: TObject; E: Exception);
var
pClassName1,pClassName2:PChar;
begin
pClassName1:=PChar(Format('%s',[E.ClassName]));
pClassName2:=PChar(Format('%s',[Sender.ClassName]));
if (StrComp(pClassName1,PChar('EConvertError'))=0 ) and
(StrComp(pClassName2,PChar('TDBGrid'))=0 ) then
//do your thing...Such as ShowMessage('I like PLMMs!');
raise Exception.Create('数据类型不匹配!');
end;

//注:在Debug状态下,Delphi 的Debug系统会先于AppException 执行,所以截获不
// 到错误。
// 请去掉RTL,生成非Debug程序运行。
// 呼,好饿好饿,找点吃的先。
 
98. Delphi中获得BDE、ADO的错误号
Delphi的数据库对象,如Ttable和TadoTable有以下一些Error事件:OnDeleteError、OnDeleteErro、OnPostError。这些事件的定义如下,都是数据集错误:
type TDataSetErrorEvent = procedure(DataSet: TDataSet; E: EDatabaseError; var Action: TDataAction) of object;
property OnPostError: TDataSetErrorEvent;

在这些事件在EdatabaseError中是无法得到错误号的,其中只有Message属性。在发生BDE错误时可如下得到错误号:
if E is EDBEngineError then
showmessage(inttostr(EDBEngineError(E).Errors[0].ErrorCode));
也可以这么写:
if E is EDBEngineError then
showmessage(inttostr((E As EDBEngineError).Errors[0].ErrorCode));
但在发生ADO错误时不能这样: E is EadoError。
其实Ado错误在数据集相应的数据库连接中都有:TadoConnection.Errors。
procedure TForm1.Table1PostError(DataSet: TDataSet; E: EDatabaseError;
var Action: TDataAction);
var
i:integer;
begin
memo1.Lines.Add(inttostr(table1.Connection.errors.count ));
for i:=0 to AdoConnection1.errors.count-1 do
begin
memo1.Lines.Add('number:'+inttohex(AdoConnection1.errors.Number,8 ));
memo1.Lines.Add('NativeCode:'+inttostr(AdoConnection1.errors.NativeError ));
memo1.Lines.Add(inttostr(AdoConnection1.errors.HelpContext ));
memo1.Lines.Add(AdoConnection1.errors.Source );
memo1.Lines.Add(AdoConnection1.errors.SQLState );
memo1.Lines.Add('Description:'+AdoConnection1.errors.Description );
end;
memo1.Lines.Add('error Msg :'+e.message);
end;
NativeError是Foxpro的原生错误号,非常详细,一般用这个来判断发生的错误。Number是Sql错误号,是大的分类,一般一个Number和多个NativeError对应。
这些错误码的信息在文档Drvvfp.hlp中都有。

 
//恩恩,这位兄台分析的很有道理。
//恩恩,不知道兄台有没有测试过?
//小生测试的结果是:兄台的方法似乎不能解决楼主的问题,象EConvertError类的数据转换错误。
//原因初步估计此类错误是于TDBGrid、TDataSource跟TDataSet三者之间raise的,并不属于数据库服务器端返回的错误。
//呼呼,好累好累,睡觉先。
 
问题依旧啊!!!
 
To 电脑农民:
胡说!你有没有用小生的方法试过?
Build工程后,注意,一定要Build!双击运行程序(别在Delphi里面直接运行!),如果在DBGrid输入了错误类型的数据,
会截获到EConvertError类的也就是你说的那类错误。
//--------------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnException := AppException;
end;

procedure TForm1.AppException(Sender: TObject; E: Exception);
begin
if (E is EConvertError) and (Sender is TDBGrid) then
//do your thing...
ShowMessage('当前数据类型与源数据类型不匹配!')
else ShowMessage('错误类型:'+E.ClassName+#13+'错误消息:'+E.Message);
end;
//--------哇靠!三百分还真不容易得!------------------
 
TO:kyo_2000
我不知道我胡说什么了,还请明示!
你的方法早在第一位仁兄(wangyufan兄)的回答里就有了,而且我上面也说了,是可以捕获的,
但这不是我要的效果,原因上面有,自己看吧。

>//--------哇靠!三百分还真不容易得!------------------
如果你完全为冲着这300分来的,那下次有简单点的问题我再通知你好吗?
请恕我这次问题的要求有点苛刻了!
 
Midas程序中捕獲ado的原生錯誤代碼有兩種方式:
1)在server端中捕获.
2)在client端加入一delphi自帶的模塊(reconcile error dialog),
然后在clientdataset中通過onreconcileerror事件捕獲.
 
刚试了一下,不管是TDBGrid,TDBGridEh,TTeThemeDBGrid都有这个错误,而且不是在POST后
出现的,是在失去焦点后出现的,可能要分析TCustomGrid的源码了,我看得发晕了,关注中
 
DBGrid赋值使用的CustomDBGrid的UpdateData过程,所以只要修改DBGrids的原码,在赋值时
自己截获一下异常就可以了,修改如下:
procedure TCustomDBGrid.UpdateData;
var
Field: TField;
begin
Field := SelectedField;
if Assigned(Field) then
begin
try //add
Field.Text := FEditText;
except //add
on E: Exception do ShowMessage(E.Message); //add
end; //add
end;
end;
如果想让修改后的文件生效,只要将其保存到自己的工程目录中,并加入工程进行编译就
可以了。

不知我回答的是否你想要得,祝你好运。。。。
 
看来只有修改源码了,不知道还有没有其它办法!
 
你的应用程序没有错误处理吗?
在应用程序主窗体添加一个TApplicationEvents控件,在OnException事件中判断
procedure TFrmMain.AppMainException(Sender: TObject; E: Exception);
begin
。。。。。。
if E is EDataBaseError then begin
// 当前编辑数据输入是否正确?;
end;
。。。。。。
end;
二楼的捕获的是全局错误,不能确定到底是哪个窗口上的哪一个错误,比较笼统;

看了这段话,如果你要确定是哪个窗口中的哪个错误,你可以用Sender参数确定错误来自
哪个窗口,哪个控件!代码如下:

procedure TFrmMain.AppMainException(Sender: TObject; E: Exception);
begin
。。。。。。
if E is EDataBaseError then begin
if (sender is tdbgrid) then
begin
memo1.Lines.add(tdbgrid(sender).Name);
memo1.Lines.add(tdbgrid(sender).Parent.Name);
end;
end;
。。。。。。
end;




 
try
...
except

...
end;
 
TO 电脑农民:
阁下甩得出分数,小生就敢要!
在大富翁里你可以回答别人的问题而大大方方地说“我不要分!”,
但你向别人问问题不得不给分,管他人是什么目的而来?
问题对于阁下或许不容易,也别不允许其他人可以轻松解决。
阁下说:“只想在ADOQuery发生“数据提交”异常时,捕获该异常并显示
相关信息”,试问,在单个数据表格单元中已经发生“正修改数据跟数据字段类型不符合”
错误,根本就还没有也不可能进行“数据提交”操作(即便是离线数据集也不可以),小生
请问阁下如何得来“ADOQuery发生‘数据提交’异常”?不知此是否谓之“胡说”也?
在DBGird中修改数值型字段值,比如输入‘1.2.3’,失去焦点后立刻产生异常,
没错,原因就是程序执行到了:
Field.Text := FEditText;
此时需要进行FEditText跟Field.Text的数据类型匹配,抛出的是Application级的异常。
需要指出的是,即使是修改源代码也没有达到阁下要的“只想在ADOQuery发生“数据提交”异常时,捕获该异常并显示
相关信息”效果,甚至比捕获全局错误的方法更不方便,例如是否能处理用户输入了错误的关键字段数值的错误?




 
TO:kyo_2000
按一般的理解,“数据提交”异常是发生在POST之后,而我说了,是在DBGRID中直接修改数
据,而此时,DBGRID是将数据基本类型验证和POST放于同一个物理操作过程中的,如发生
NEXT操作或在编辑状态时用MOUSE随便点一下其它行时即是如此。因而在我看来,我提问题
时不会说是在“数据类型验证”时发生异常,而只会说是“数据提交”时发生异常。

按你的说法,这个问题就根本不是问题,或者说如果称之为“问题”,那也是无法解决的,
因而称之为“胡说”。
不过我要告诉你,我已解决好了,而且成功捕获了。方法正是修改了源码,当然,不是上面
的修改方法,而且一劳永逸(重装DELPHI另算了)。

不过还是要感谢你的帮助。
 
灌水的人太多了
 
大功告成了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部