vb编程对错误处理_第1页
vb编程对错误处理_第2页
vb编程对错误处理_第3页
vb编程对错误处理_第4页
vb编程对错误处理_第5页
免费预览已结束,剩余18页可下载查看

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第6章对错误的处理即使程序员最好的愿望,而且计划工作做得非常周密,也无法避免代码出现错误。这些错误可能是编程员的错误(0错误(比如想要保存的文件太大,磁盘上的空闲空间放不下,或者是时间上的错误(比如试图给尚未完全加载的窗体设置焦点。应该努力编写没有错误的代码,不过创建每个过程时也应该假设它可能出现错误。这意味着每个过程必须包含错误处理程序。实际上可能出现的程序错误的数量是很大的,但是它们基本上可以分为两种类型:一种是isualBacsic的编译器无法对代码进行编,iualBaic将不执行该过程,并且你也不能向用户提供带有编译错误的运行期版本应用程序。大多数编译错误是句法错误造成的。PublicSubMyProcedure(intMyVariableAsCall语句中增加了CallMyProcedure(invVariable1,运行期错误是在程序运行时产生的,并且通常是试图对变量执行无效操作而产生的结果。例如,下面这个代码不会产生编译错误(如果intMyVariable是个已经说明的变量,那么它的句。Print10/intyVariable的值是0,VisualBacsic10不能被0除。如果在IDE中运行一个项目时出现一个运行期错误,代码就会在出错的代码行上停止运行,并显示一条出错消息。在已经编译的程序中,处理的错误是致命的,它会导致整个应用程序运行瘫痪。通过创建错VisualBasicVisualBasic有两个设置在很大程度上影响你创建非常坚实的代码的能力。一个设置项是CompileOnDemand(按需要进行编译,另一个设置项是BackgroundCompile(编译。可以打开Options框,选定General选项卡,然后对这两个设置项进行设置,如图6-1所示。当选定CompileOnDemand时,如果单击上的un按钮,或者按F5键,ViualBaic并不全面编译你的项目。相反,只在过程时,才对这些过程进行编译。使用CompileOnDemand,通常可使比较大的项目或者速度较慢的计算机上的项目能够更快地启动运行,但是它也会产生某些不被注意的编译错误。 如果按Ctrl+F5键,或者从Run菜单中选择StartWithFullCompile(启动全面编译),那么不管你是否选定CompileOnDemand设置项,都会使项目得到全面编译。图6-1进行编程时,CompileOnDemand和Background.exe或.dll选定CompileOnDemand并不能够发布带有编译错误的代码。但是,选定CompileOnDemand后,会导致编译错误随着时间的推移而不断增加,从而在最后试图进行全面编译时,迫使你对代码进行大量的纠错。如果在IDE中调试项目,你会变得心烦意乱,因为VisualBasic常常必须停止(不只是暂停)运行,以便进行纠错操作。这使得调试正在运行的项目时对大量编译错误的纠正操作变得非常麻烦。如果你的计算机能够在合理的时间内全面编译项目,那么可以考虑关闭CompileOn。也可以使pileOnDemand保持选定状态,但是要定期按Ctrl+F5便重新运行你的项目。这使你在编程时能够定期纠正编译错误,而不必纠正大量的编译错误。选定CompileOnDemand时,也可以决定是否选定BackgroundCompile选项。如果选定BackgroundCompile,就可以在过程和模块被时对它们进行编译,不过VisualBasic也使用空闲时间对尚未的模块进行编译。随着时间的推移,项目就可以得到全面编译。使用BackgroundCompile选项,可以更快地加载全面编译的项目,并使编译错误保持在最低水平,因为你会随时关注未被的模块中的错误。同样,你应该知道纠正编译错误常常会迫使在能够编写有效的错误处理代码之前,你必须了解VisualBasic的Err对象,这是个运行期对象,它包含了关于错误的信息。当程序运行时遇到一个错误,或者当你使用Err对象的Raise方法故意一个错误时,便形成Err对象的属性。当遇到OnError语句(比如OnErrorResumeNext),并且在使用ExitSub、ExitFunction或ExitProperty语句退出一个过程后,Error对象的属性值就被清除。若要显式清除Err对象,可以表6- 用于标识该错误的号 当前Visualbasic项目的名 与错误相关的VisualBasic帮助文件所在的驱动器、路径和文件 VisualBasic帮助文件用于该错误的上下文asDrr 在32位ndows操作系统上,上次调用动态库(D)的系统错误代码。asDlrror属性是只读属性意,Err对象的属性被设置为该错误的相应值。如果需要使用些值中的任何一个值,应该立即对它们进行操作,或者在执行其他操作之前将它们存放在一个变量中,因为ErrErr对象中的属性值只能,Err象并不错误史信息列表。将一个项目当作已经编译的程序运行时,未捕获的错误会造成致命的,它们会导致程序终止运行。必须尽一切努力防止发生这种情况。若要防止代码中的错误中码的运行(并终止已编译程序的运行iualBaic并不显示出错消息,也不终止代码的运行。相反,你编写的专门用来处理错误的代OnError代码错误会将过的错误处理程序的调用栈“提升”到堆栈中的较置(本章后面将详细介绍。如果一个过程的错误能够以这种方式出现,就应该在过程的开头用突出的注释来明确说明这一行为特性。当出现错误时,使用On 使用OnErrorResumeNext语句,不中码的执行,也不转移到别的代码上去执行,而可以在一个过创建多个错误处理程序,但每次只能激活一个错误处理程序。isualBasic将的OnError语句中指明的处理程序视为已经激活的错误处理程序。切换一个过的不同位置上的错误处理程序,往往是很有好处的,理解各个错误处理程序如何运行,是利用这能的关键。使用OnResumeNext对错误进行处理的最简(和最)的方法是使用OnErrorReumeext语句。OnErrorResumeNext语句规定,代码中的错误将完全被忽略,存在错误的代码行被跳过,然后继续执例如,下面这个过程存在一个运行期错误(0除的错误),它由OnErrorResumePrivateSub‘*Purpose:TestOnErrorResumeOnErrorResumeDebug.Prin10/EndDebug.print语句产生了一个被0除的错误。但是,由于存在一个已经激活的错(由OnErrorResumeNext指定),因此该错误被忽略,并在下一个语句(即EndSub语句)上恢没有显示出错消息,Err对象仍然包含关于该错误的信息。下面这个过程说明了如何随时测试11∶Divisionbyzero。PrivateSub‘*Purpose:DetectanerrorusingtheErrOnErrorResumeNextDebug.Print10/0‘*Ifanerroroccurred,displayitsnumberandIfErr.Number>0MsgBoxErr.Number&“:“&Err.Description,EndEnd这种方法有许多用处。例如,你想用输入文本框的数据在数据库中创建一个新记录,但是创建记录的表格中不允许相重的值。你可以设法找出与文本框中的输入数据相一致的记录,然Error3022(记录),如下面的过程所示:PrivateSub‘*Purpose:Createarecordina fromthedataontheOnErrorResumeDimrstMyTableAsConstc_DuplicateRecordError=‘*CreateaRecordsetfromthemodule-levelDatabaseSetrstMyTable=m_dbMyDatabase.OpenRecordset(“MyTable",‘*Attempttoaddanewrecordtothedatabase.rstMyTable.AddNewrstMyTable![Name]=txtName.TextrstMyTable.Update‘*TestforduplicatevalueIfErr.Number=c_DuplicateRecordErrorMsgBox“Thisnameexistsinthedatabase,andduplicates“&“arenotallowed.”,EndSub注意nEroreuee象打交道后,检查Err对象,你肯定能够知道是哪个对象导致了错误的发生,这个对象就是在Err.Source除非你捕获了一个意料之外的错误,比如前面代码中的那种错误,否则忽略代码中的错误是非常的,并且是一种不得已时采用的办法。当一个过出现了意料之外的错误时,该过程就会产生许多问题。如果忽略该错误,就会对用户产生严重的影响,比如数据没有保存,或者保存不正确。许多况下,当出现代错误时,须执行某些操作,将代的执行转移到OnErr oTo语句中指定的误处理程序。语句的法如下:On oToli请注意,line必须是指与On 在这个句法中,line有两个意思。首先它是现错误时要转移到的这个代码行号。不过PrivateSub‘*Purpose:TesttheOn oTostatementby generatingarun-On oToDebug.Print“LineDebug.Print10/Debug.Print“LineDebug.Print“LineEnd你可能认为,被0除的错误会导致代码在输出文本line4这个语句上继续执行,因为这是代码的第四个语句(不是计数注释。不仅这种情况不会发生,而且该代码实际上会导致产生一个编译错误,并且代码根本不会执行。当指定一个行号时,你必须用该行号作为某个特定语句的标记,如下所示:PrivateSub‘*Purpose:TesttheOn oTostatementby generatingarun-timeOn oToDebug.Print“LineDebug.Print10/Debug.Print“Line4Debug.Print“LineEnd行的语句。你使用的实际号码是不连贯的,它们不必对应于实际行号,也不必按任何顺序来排列。注意不能使用0作为行号。0有它的特殊用处,在后面介绍line的第二个和更常见的用处是提供一个行标注。行标注是个文本串,用于标识一个单行代码。行标注可以是任何字符的组合,它以一个字母开始,以冒号()结尾。例如,下面这个过程包含一个标记。当出现被0OnErroTo语句转移到标注为PROC_ER的PrivateSub‘*Purpose:UsealinelabeltodivertcodeOn oToDebug.Print“LineDebug.Print10/Debug.Print“LineDebug.Print“LineEnd注意标注应该全部使用大写字母,使之更加醒目。另外,不应该将多个语句放在一个代码行上,这条规则也适用于标注,因为标注也被视为代码语句。当控制转移到标注nErrorTo时才执行错误处理程序,应该在错误处理程序前面加上Extb、Eituntin或Eitroerty语句(如果遵守第2章中的编程说明2.3.2,Eit语句将紧随RCEIT标注之后,并且将是过PrivateSub‘*PurposeOn oToExitEnd在这个代码例子中,一个代码错误导致代码的执行跳到PROC_ERR标注处,然后,代码继续执行,直到它到达EndSub语句为止。不必让代码运行通过该过程的剩余部分,直到它到达EndSub、EndFunction或EndProperty语句。也可以执行下列操作:使用一个ExitSub、ExitFunction或ExitProperty语句,迫使代码的执行退出该过程(请使用GoToPROC_EXIT与ExitSub、ExitFunction或ExitProperty语句的组合,强制代码的PrivateSub‘*Purpose:TestthebehaviorofGoToinanerrorOn oToDebug.Print10/0ExitMsgBoxMe.Name&“|MyProcedure”&vbCrLf&Err.Number&vbCrLf&_GoToEndPrivateSub‘*Purpose:TestthebehaviorofResumeNextin errorOn oTo‘*ErrorisgeneratedonthenextDebug.Print10/Debug.Print“CodeReturnsExitMsgBoxMe.Name&“|MyProcedure”&vbCrLf&Err.Number&vbCrLf&_ResumeEnd这个过的错误使得代码转移到PROC_ERR块中的代码而继续执行。当遇到Resume使用下面所示的Resume<line>,你可以转移到产生错误的过的某个代码语句。line参数的作用与它在OnErrorResume<line>语句中的情况相同。PrivateSub‘*Purpose:DemonstrateResume<line>inanerrorOn oToDebug.Print“LineDebug.Print10/Debug.Print“LineDebug.Print“Line5"ExitResumeEnd错误处理程序最擅长的功能也许是它能纠正错误。如果它能纠正错误,将控制权返回给出错的语句,那么代码几乎就象从未发生过错误一样。虽然纠正错误所用的方法取决于当时的条件,但是返回到出错的代码行是很简单的,并且是连贯一致的。若要使代码返回到产生错误的语句继续执行,请使用ResumePrivateSub‘*Purpose:DemonstratetheResumestatementin errorOn oToDimintFileNumberAsIntegerDim AsConstc_MaxRetries=Constc_LockedFileError=70intFileNumber=1Open“C:\Test.txt”ForOutputAsExit‘*Iftheerrorindicatesthatthefileislocked,attemptto‘*thefileagainuntilc_MaxRetriesattemptshavebeenIfErr.Number=c_LockedFileError‘*If umnumberofattemptshasbeen l‘*userthatthefileislockedandgetIfintRetries>c_MaxRetriesMsgBox“Fileislocked!",GoToEnd‘*CallacustomPauseprocedurethatpausesa‘*numberofCallintRetries=intRetries+EndIfEnd这个代码例子设法打开一个名叫:\est.txt的文件。如果该文件被另一个应用程序锁定了,就会出现一个错误,代码将转到错误处理程序继续执行。然后错误处理程序负责执行下列操作:如果错误处理程序被调用的次数少 C_MaxRetries规定的最大次数,它将调用一个自义的Pause(暂停)例程。然后intRetries的值递增,并返回Open语句继如果错误处理程序调用的次数超过了允许的次数,便向用户显示一条消息,同时退出该过程。有一个非常重要的问题你必须了解,那就是错误如何在调用栈中向上移动。为了理解这个问题,有两个术语是必须介绍的。一个术语是“已激活的错误处理程序”,指OnError语句中最近指定的错误处理程序。另一个术语是“活动的错误处理程序”,指正在处理错误的进的错误处理程序。请注意,可能存在这样一种情况,即错误处理程序已经被激活,但它不是活动的处理程序。一旦错误处理程序被激活,它将保持激活状态,直到另一个错误处理程序被激活,或者包含错误处理程序的过程超出其作用域为止。当包含错误处理程序的过程超出其作用域时,便返回调用过程继续执行,同时上次被激活的错误处理程序再次被激活。PrivateSub‘*Purpose:EnableanerrorhandlerandcallanotherOnErrorResumeNextCallTestSubEndPrivateSub‘*Purpose:DemonstrateerrorhandlersandthecallOn oToDebug.Print10/0ExitGoToEnd当cmdCreateErrorHandler按钮被点击时,OnErrorResumeNext语句便激活一个错误处理程序。当TestSub过程被调用时,它的错误处理程序就变为激活状态,在TestSub过遇到的任PrivateSubcmdCreat‘*Purpose:EnableanerrorhandlerandcallanotherOnErrorResumeNextCallTestSubEndPrivateSubTestEndClick事件中的OnErrorResumeNext语句就激活一个错误处理程序。当TestSub过程被调用时,该过的错误处理程序将变成激活状态。由于TestSub过程不包含任何错误处理程序,因此,在执行TestSub过程的期间,激活的错误处理程序(通过Click在TestSub过遇到一个错误时,将会发生什么情况呢?下面两个过程说明了这种情况PrivateSub‘*Purpose:DemonstrateerrorhandlersandthecallOnErrorResumeNextCallTestSubMsgBox“Statement procedure",EndPrivateSub‘*Generatearun-timeDebug.Print10/MsgBox“Statemenaftererror",End当Click事件被时,便使用OnErrorResumeNext激活一个错误处理程序。当代码的执行转移到TestSub过程上时,该错误处理程序将保持激活状态,因为在TestSub过没有激活任何错误处理程序。当出现被0除的错误时,将会输出什么呢?由于TestSub过不存在错误处理程序,代码的执行便直接返回调用过程(即CmdCreateErrorHandler_Click过程),由它的已激活的错误处理程序对它进行处理。由于该错误处理程序是个ResumeNext错误处理程序,因此,你可能认为紧跟在错误后面的语句(在TestSub过)将是下一个要执行的语句。实际上并非如此。紧跟在对TestSub调用的后面的语句将成为下一个执行的语句,并输出文本“Statementin procedure”。OnError语句不能将代码的执行引向它所在过程的外面。这个概念也适用于多个嵌套的过程。如果在一个过出现错误,而该过程并没有已激活的错误处理程序,那么就要检查调用带有错误的过程的那个过程,以便找出已经激活但并不是活动的错误处理程序。这个检查将在调用栈中连续向上进行,直到找出一个已激活但并不是活动的错误处理程序,或者到达调用栈的顶部。如果到达了调用栈的顶部,该错误即被视为未捕获的错误。如果遇到一个已被激活但不是活动的错误处理程序,便执行该错误,然后在包含该处理程序的过继续行。使用On 有时需要在运行时取消已激活的错误处理程序的激活状态。在本章的开头,讲过,当使用OnErroTo语句时,不能使用行号0。这是因为使用行号0会使当前已激活的错误处理PrivateSub‘*Purpose:Demonstratedisablinganerror arunOn oToOn oToDebug.Print10/0ExitCallShowError(Me.Name,“cmdDisableErrorHandler",Err.Number,_GoToEnd该过的第一个语句用于激活一个错误处理程序。但是OnErrorGoTo0语句则用于取消错误处理程序的激活状态。因此,被0除的错误就不能捕获,同时VisualBasic将显示一条出错注意OnErrorGoTo0只能使当前过的错误处理程序取消激活状态。如果OnErroTo0语句后面遇到了一个错误,该错误将在调用栈中向上传递,就象该过程中根本没有错误处理程序一样。如果在调用栈中的较置上找到一个已激活但不是让VisualBasic中止代码的执行,这样做常常是非常不利的。当代码的执行中止时,会看到一条相关的出错消息,并告诉你出现错误的代码行,这对于代码的调试来说是大有帮助的。VisualBasic为处理代码设计时遇到的错误而使用的方法取决于VisualBasicIDE的ErrorTrap属图6-2选定Options框中General选项卡上的一个选项,就能改 ErrorTrap(捕获错误属性是VisualBasic环境的一个属性,不是某个项目的属性。你操作的每个项目,即使在关闭和重新启动VisualBaic之后,均使用该设置值。若要为isualBasic的当前会话设置ErrorTrap选项,而不必为将来的会话修改默认值,请使用代码窗口的快捷菜单上的oggle命令(见图6-3。图6-3从任何代码窗口的快捷菜单中选择Toggle命令,就可以为BreakOnAllErrors(在所有错误上中止BreakInClassModule(在类模块止BreakOnUnhandledErrors(在未处理的错误上中止BreakOnAllErrors实际上可使所有错误处理程序均取消激活状态。当出现一个错误时,VisualBasic显示一条出调试ActiveX组件时,BreakInClassModule设置值是最有用的。一般来说,调用ActiveX组件的方法的过的已激活错误处理程序,将负责处理ActiveX组件的过尚未处理的任何错误。BreakInClassModule设置值规定,不在ActiveX组件中处理的错误,会使ActiveX项目在产生该错误的语句上进入中止方式。这将使不是在ActiveX组件中处理的错误无法在调用栈BreakOnUnhandledError设置值能够非常接近地模仿错误在已编译程序中被处理的情况。被已激活的错误处理程序捕获的错误将由这些处理程序进行处理,并且只有未处理的错误才会将错误处理功能添加给项目中的所有过程,这是件令人感到乏味的工作,但却是必须做的一件事情。意料之外的所有错误都必须以相同格式向用户显示,这需要编写相当长的代码。如果增加一个错误处理程序,事情就好办了。错误处理程序是在出现错误时调用的一个过央错误处理程序至少能够向用户显示格式一致的出错消息。不过也可以在你认为合适的时候给错误处理程序增添一些功能。例如,每当出现意料之外的错误时,可以让你的错误处理程序将一个电子邮件发送给支持技术,也可以增加一些代码,对机器的运行状态制作一个瞬态图,并将已加载的应用程序和DLL及其版本记录下来。FriendSubShowError(strModuleAsString,strProcedureAsString,_lngErrorNumberAsLong,strErrorDescriptionAsString)‘*Purpose:Provideacentralerror-handling‘*Accepts:strModule-themoduleinwhichtheerror encountered(form,class,standard,andso strProcedure-thenameoftheprocedurein theerrorwas lngErrorNumber-thenumericidentifierof strErrorDescription-thetextdescription theOnErr oToPROC_ERRDimstrMessageAsStringDimstrCaptionAs‘*BuildtheerrorstrMessage=“Error:“&strErrorDescription&vbCrLf&vbCrLf&“Module:“&strModule&vbCrLf&“Procedure:“&strProcedure&vbCrLf&vbCrLf&_“PleasenotifyMySoftware’stechsuppor“&_“at555-1213aboutthisissue.”&vbCrLf&_“Pleaseprovidethesupporttechnicianwith“&_“informationshownin“&vbCrLf&“thisdialog“&_“boxaswellasanexplanationofwhatyou“&_“were”&vbCrLf&“ ngwhenthis“&_“error‘*Buildthecaptionforthemessagebox.Thecaption‘*theversionnumberofheprogram.strCaption=“UnexpectedError!Version:“&_Str$(App.major)&“.”&Str$(App.minor)&“.”&Format(App.Revision,MsgBoxstrMessage,vbCritical,strCaptionExitResumeEndPrivateSub‘*Purpose:Generateanerrorbysettingthefocus aninvisibleOn oTo‘*Setthefocustoaninvisiblecontrol.txtCity.Visible=FalseExitCallShowError(Me.Name,“frmMain_Click",Err.Number,ResumeEnd当出现上面这个代码中所示的错误时,错误处理程序即被调用,并且显示图6-4所示。到别的过。在窗体过,只需要更改。

Me.Name不起作用,为此你必须使用原义类名字。不过,在这种情况下,最好创建一个模块及常量,并使用该常量,这样,当模块的名字被更改时,可以非常容易地修改类模块中的错误处理程序。如果使用通用常量名,可以拷贝一个模块的Call语句,再将它们粘贴到另一个模块中,而不必进行重大的修改。虽然前面介绍的错误处理程序能够以的格式向用户显示出错消息,但是你必须确定除了调用ShowError过程外,每个错误处理程序拥有什么代码。例如,错误处理程序究竟需要Resume还是Resumeext语句呢?也许它需要一个GooPROC_EXIT语句。应该尽可能使你的错误处理程序具备通用性,不过要确保每个处理程序适用于它所在的过程。将发生的所有错误记录在一个文件中,这常常是非常有用的。例如,在项目的测试阶段,必须尽量全面地了解发生的错误。你往往不能依赖用户提供的报告。当你非常需要了解程序中出现的每个错误时,应该使用错误处理程序创建一个出错日志文件。出错日志文件的创建很简单。首先创建一个前面介绍的错误处理程序。然后,在错误处理程序中建立一个机制,将错误记录到一个文本文件中。下面这个代码展示了将错误记录在文本文件中所用的法。这个代码显示的情况与它面介绍的作为错误处理程序的一部分的情况是一样的。它的前提是,该过存在若干局部变量,并且在称为g_trErrorLogFileName的项目中有一个全局变量,它包含了出错日志文件的路径和名字。Dim As‘*OLogFile=FreeFile‘*OpentheerrorlogtextfileinAppendmode.‘*Ifthefiledoesn’texist,theOpenstatement‘*createsit.Openg_strErrorLogFileNameForAppendAs‘*WritethePrint#intLogFile,“***ErrorEncountered“&VBA.Now&“***"‘*Writethepertinenterrorinformationtothelogfile.Print#intLogFile,“Error:“&Print#intLogFile,“Description:“&Print#intLogFile,“Procedure:“&Print#intLogFile,“Module:“&‘*WriteablanklinetothelogPrint#intLogFile,‘*ClosethelogClose这个代码试图打开全局变量g_strErrorLogFileName中用Append方式设定的文本文件。如果该文件不存在,该代码便自动创建该文件,然后将它打开。一旦文件被打开,便写入一个日志5行文本,各个日志项之间用一个空行隔开。下面是用上面的代码创建的一个文本文件举例:***ErrorEncountered8/29/994:19:18PM***Error:5Description:InvalidprocedurecallorargumentProcedure:ShowCustomerModule:***ErrorEncountered8/29/994:20:08PM***Error:11Description:DivisionbyzeroModule:mdlScience***ErrorEncountered8/29/994:22:05PM***Error:6Description:OverflowModule:mdlScience***ErrorEncountered8/29/994:22:34PM***Error:11Description:DivisionbyzeroModule:mdlScience在这个错误日志文件中,你可以看到一个趋势。无论是谁编写mdlScience模块,都需要在列入的信息。例如,可以列入出现错误时运行程序的这个人的用户名,也可以将机器名列入日志项。可以列入的信息是不受限制的。无论选择何种信息来列入日志文件,务必列入有助于查找和纠正错误的相关信息。FriendSubShowError(strModuleAsString,strProcedureAsString,_lngErrorNumberAsLong,strErrorDescriptionAsString)‘*Purpose:Provideacentralerror-handling‘*Accepts:strModule-themoduleinwhichtheerror encountered(form,class,standard,andso strProcedure-thenameoftheprocedurein theerrorwas lngErrorNumber-thenumericidentifierof strErrorDescription-thetextdescription heOnErr oToPROC_ERRDimstrMessageAsStringDimstrCaptionAsStringDimintLogFileAsInteger‘*OLogFile=FreeFile‘*OpentheerrorlogtextfileinAppendmode.‘*Ifthefiledoesn’texist,theOpenstatement‘*createsit.Openg_strErrorLogFileNameForAppendAs‘*WritethePrint#inLogFile,“***ErrorEncountered“&VBA.Now&‘*WritethepertinenterrorinformationtothelogPrint#intLogFile,“Error:“&Print#intLogFile,“Description:“&Print#intLogFile,“Procedure:“&Print#intLogFile,“Module:“&‘*WriteablanklinetothelogPrint#intLogFile,‘*ClosetheerrorlogtextClose‘*BuildtheerrormessagefordisplaytothestrMessage=“Error:“&strErrorDescription&vbCrLf&vbCrLf&“Module:“&strModule&vbCrLf&“Procedure:“&strProcedure&vbCrLf&vbCrLf&_“PleasenotifyMySoftware’stechsupport“&_“at555-1213aboutthisissue.”&vbCrLf&_“Pleaseprovidethesupporttechnicianwith“&_“informationshownin“&vbCrLf&“thisdialog“&_“boxaswellasanexplanationofwhatyou“&_“were”&vbCrLf&“ ngwhenthis“&_“error‘*Buildthecaptionforthemessagebox.Thecaption‘*theversionnumberofthestrCaption=“UnexpectedError!Version:“&_Str$(App.major)&“.”&Str$(App.minor)&“.”&_Format(App.Revision,“0000”)MsgBoxstrMessage,vbCritical,ExitResumeEnd当你的应用程序将要记录出错消息时,必须确定你想用这些日志信息来干什么。如果在程序运行的现场,你可以人工检索出错日志的拷贝。也可以在用户遇到问题时让他们用电子邮件将日志发送给你。甚至可以编写一个程序,让它按照预定的计划用电子邮件将日志发送给你。在查找特定的错误和一般程序错误方面,日志文件是非常有用的。而且日志文件的创建非常容易。你应该认真考虑将这个特性添加给你的程序。甚至可以选择包含它的代码但默认关闭这个特性。后通你的序的面或通过表设,激活取消活日文件生成能 使用On OnErroTo语句是指定要使用的错误处理程序的最常用方法。除非有特定的理由来使用另法,否则在你的所有过都应该将这种方法用作默认方法:PrivateSubimgEditor_MouseUp(ButtonAsInteger,ShiftAsInteger,_XAsSingle,YAsSingle)‘*Purpose:Iftheeditorisinselect(marquee)mode, theEdit whentheuserright- theOnErrorResume‘*Displaythe onlyiftheuserclicked‘*therightmouseIfButton=vbRightButton‘*SeeiftheactivetooloftheCanvasobjectis‘*marqueeIfg_objCanvas.ToolIndex=bdMarquee‘*DisplaytheEdit usingthe‘*barcontrol.EndIf ltheCanvasobjecttostopitscurrentaction.g_objCanvas.ActionEndButton,Shift,X,YExitEndPrivateSubimgEditor_MouseUp(ButtonAsInteger,ShiftAsInteger,XAsSingle,YAs‘*Purpose:Iftheeditorisinselect(marquee)mode, theEdit whentheuserright- theOn oTo‘*Displaythe onlyiftheuserclicked‘*therightmouseIfButton=vbRightButton‘*SeeiftheactivetooloftheCanvasobjectis‘*marqueeIfg_objCanvas.ToolIndex=bdMarquee‘*DisplaytheEdit usingthe‘*barcontrol.EndIf lheCanvasobjecttostopitscurrentaction.g_objCanvas.ActionEndButton,Shift,X,YExitCallShowError(Me.Name,“imgEditor_MouseUp",Err.Number,_EndSub使用OnErrorResumeNext当你估计会出现一个错误时,比如使用SetFocus将光标移到没有完全加载的窗体中的一个控件上时出现的Error5,或者数据库操作产生的一个错误,请使用OnErrorResumeext不过要注意,使用OnErrorResumeNext语句可能有一定的,因为它会使你注意不到运行期的错误。不要将这个语句当作万应灵药来使用,如果你估计不会出现错误,则不要用它。另外,仅为估过能现误也不着应将OnErrorResumeNext句用于整个过程。使用OnErroTo语句可以捕获意料之外的错误,但是要修改紧靠可能产生预期错误的代码行前面的已激活错误处理程序。当你对预期的错误进行处理后,加上一个OnErroo语句,再次激活主要的错误处理程序。OnErrorResumeNext语句,比如你预期出现什么错误,为什么会出现这个错误。PrivateSub‘*Purpose:Allowtheusertobrowseandselecta pageforOnErrorResumeConstc_CancelChosen=‘*Usethecommondialogcontroltoallowtheuser‘selectaWith.fileName=.DefaultExt=.DialogTitle=“SelectCover.Filter=“AllFiles(*.*)|*.*|CoverPages.FilterIndex=.InitDir= lthecontrolfogenerateanerrorifCancelis.CancelError=‘*ShowtheOpenFiledialogboxandwaitfortheuser‘*selectafileorclick‘*Seeifanerrorwasgeneratedastheresultof‘*userclickingIfErr.Number=c_CancelChosenThen‘*Cancelwasclicked;getout.GoToPROC_EXITEndtxtCoverpage.Text=EndExitEndPrivateSub‘*Purpose:Allowtheusertobrowseandselecta pageforOn oToConstc_CancelChosen=‘*Usethecommondialogcontroltoallowtheuser‘*selectaWith.fileName=.DefaultExt=.DialogTitle=“SelectCover.Filter=“AllFiles(*.*)|*.*|CoverPages.FilterIndex=.InitDir= lthecontroltogenerateanerrorifCancelis.CancelError=‘*IftheuserclicksCancel,arun-timeerror‘*TrapforthisOnErrorResume‘*ShowtheOpenFiledialogboxandwaitfortheuser‘*selectafileorclick‘*Seeifanerrorwasgeneratedastheresultof‘*userclickingIfErr.Number=c_CancelChosenThen‘*Cancelwasclicked;getout.GoToPROC_EXITEnd‘*Enablethemainerrorhandler.OnErr oToPROC_ERRtxtCoverpage.Text=.fileNameEndExitCallShowError(Me.Name,“cmdCoverLetter_Click”,Err.Number,_EndSub创建的错误处理程序使用OnErroTo语句时,很重要的一个问题是要使用的错误处理程序块。最好使用一个错误处理程序,不过如果不使用错误处理程序,请创建类似下面这个典型错误块MsgBox“ModuleName|ProcedureName”&vbcrlf&“Error:“&_Err.Number&vbCrLf&Err.Description,vbCritical‘cleanupcodesuchasaResume ‘*or oTo如果你想提醒用户注意这个错误(通常这是解决问题的最佳办法,MsgBox语句应该是

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论