news 2026/6/7 9:28:00

VB程序老崩溃?这套错误处理机制让我三年没出过事故

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
VB程序老崩溃?这套错误处理机制让我三年没出过事故

VB程序老崩溃?这套错误处理机制让我三年没出过事故

写VB的人分两种:一种是程序报错了才知道哪里出问题,另一种是程序还没崩就已经把异常兜住了。我以前属于第一种,做的库存管理系统上线第一天就崩了三次,客户打电话过来骂人。后来我花了整整两个月研究VB的错误处理机制,才真正明白:会写代码不算本事,会处理错误才算。今天这篇,把我这些年总结的异常处理方案全部摊开,直接能抄进项目里。

一、为什么VB的错误处理这么重要

☆ 1、VB是弱类型语言,运行时错误特别多。类型不匹配、下标越界、除以零、空对象引用,这些错误在编译期根本发现不了,只有运行时才会暴露。

☆ 2、企业管理系统不是你自己用的,是给文化程度参差不齐的一线员工用的。他们会在必填框里填空格,会在数字框里输入字母,会在你没想到的地方给你制造异常。

☆ 3、没有错误处理的VB程序,崩起来连个提示都没有,直接闪退。用户不知道发生了什么,只会觉得你的软件是垃圾。

我之前给一个物流公司写调度系统,因为没做错误处理,有一次数据库连接断开,程序直接白屏退出,调度员正在排单,数据全丢了。从那以后,我每个程序的第一件事就是写错误处理框架。

二、VB错误处理的三种方式

☆ 1、On Error Resume Next(最常用,也最危险)

这句话的意思是:出错了别停,继续往下执行。它适合用在你明确知道某个操作可能失败、而且失败了也不影响主流程的场景。

vb

On Error Resume Next

Dim rs As ADODB.Recordset

Set rs = conn.Execute("SELECT * FROM 员工表")

If Err.Number <> 0 Then

MsgBox "查询失败:" & Err.Description, vbCritical

Err.Clear

Exit Sub

End If

On Error GoTo 0 '关掉错误忽略,恢复正常报错

☆ 2、On Error GoTo 标签(最规范)

这是我最推荐的方式。出错后跳到指定的错误处理代码块,统一处理,处理完可以选择Resume回到出错的地方继续执行,也可以选择Exit退出。

vb

Private Sub btnSave_Click()

On Error GoTo ErrHandler

Dim sql As String

sql = "UPDATE 员工表 SET 姓名='" & txtName.Text & "' WHERE 工号='" & txtID.Text & "'"

modDB.ExecuteSQL sql

MsgBox "保存成功!", vbInformation

Exit Sub

ErrHandler:

MsgBox "操作失败:" & Err.Description, vbCritical

Err.Clear

End Sub

☆ 3、不写任何错误处理(最傻)

这种写法在VB6里也能跑,但一旦出错,程序直接崩溃,用户体验为零。如果你的程序只有自己用,那随便。如果是给别人用的,千万别这么干。

三、实战:搭一套通用的错误处理框架

我在每个项目里都会建一个modError.bas模块,把所有错误处理的公共逻辑放进去,主窗体直接调用。

☆ 1、封装一个全局错误处理过程

vb

'=== modError.bas ===

Option Explicit

Public Sub SafeExecute(procName As String, proc As Object)

On Error GoTo ErrHandler

Application.MousePointer = vbHourglass '鼠标变沙漏

Call proc

Application.MousePointer = vbDefault '鼠标恢复

Exit Sub

ErrHandler:

Application.MousePointer = vbDefault

Dim errMsg As String

errMsg = "【" & procName & "】执行出错:" & vbCrLf

errMsg = errMsg & "错误号:" & Err.Number & vbCrLf

errMsg = errMsg & "错误描述:" & Err.Description & vbCrLf

errMsg = errMsg & "发生位置:" & Err.Source

'写入日志文件

WriteLog errMsg

'弹窗提示用户

MsgBox errMsg, vbCritical, "系统错误"

Err.Clear

End Sub

Private Sub WriteLog(msg As String)

Dim fileNum As Integer

fileNum = FreeFile

Dim logPath As String

logPath = App.Path & "\error.log"

Open logPath For Append As #fileNum

Print #fileNum, Now & " | " & msg

Close #fileNum

End Sub

☆ 2、在主窗体中调用

vb

Private Sub btnSearch_Click()

SafeExecute "btnSearch_Click", AddressOf DoSearch

End Sub

Private Sub DoSearch()

Dim sql As String

sql = "SELECT * FROM 员工表 WHERE 姓名 LIKE '%" & txtSearch.Text & "%'"

Dim rs As ADODB.Recordset

Set rs = modDB.GetRecordset(sql)

Set dgvList.DataSource = rs

End Sub

这样写的好处是:不管哪个按钮出了错,都会自动记录日志、弹窗提示、鼠标恢复,用户体验一致,排查问题也方便。

四、五种最常见的运行时错误及处理方案

☆ 1、错误号3021:没有找到记录(BOF或EOF为True)

这个错误在记录集为空时特别常见。很多人直接用On Error Resume Next忽略掉,结果后面的代码全在空对象上跑,越错越离谱。

vb

Dim rs As ADODB.Recordset

Set rs = modDB.GetRecordset("SELECT * FROM 员工表 WHERE 工号='99999'")

If rs Is Nothing Then

MsgBox "查询失败,请检查数据库连接。", vbExclamation

Exit Sub

End If

If rs.EOF Then

MsgBox "没有找到该员工记录。", vbInformation

rs.Close

Set rs = Nothing

Exit Sub

End If

'正常处理数据

rs.MoveFirst

Do While Not rs.EOF

Debug.Print rs!姓名

rs.MoveNext

Loop

rs.Close

Set rs = Nothing

☆ 2、错误号91:对象变量未设置(Nothing)

这个错误说明你在用一个没初始化的对象。最常见的场景是Recordset用完没关,下次再打开时连接已经断了。

vb

'错误写法

Dim rs As ADODB.Recordset

Set rs = conn.Execute(sql) '如果conn是Nothing,这里直接报错91

'正确写法

On Error GoTo ErrHandler

If conn Is Nothing Then

InitDB '重新初始化连接

End If

Set rs = conn.Execute(sql)

☆ 3、错误号13:类型不匹配

这个错误通常发生在把文本框的内容直接拼进SQL语句时。用户输入了非数字内容,拼接后类型对不上。

vb

'错误写法

Dim age As Integer

age = txtAge.Text '如果用户输入了"abc",直接报错13

'正确写法

On Error Resume Next

Dim age As Integer

age = CInt(txtAge.Text)

If Err.Number = 13 Then

MsgBox "年龄必须是数字!", vbExclamation

txtAge.SetFocus

txtAge.SelStart = 0

txtAge.SelLength = Len(txtAge.Text)

Err.Clear

Exit Sub

End If

On Error GoTo 0

☆ 4、错误号5:无效的过程调用

这个错误通常发生在调用了一个不存在的方法,或者参数传错了。

vb

'错误写法

rs.MoveNext '如果rs已经被关闭了,这行就报错5

'正确写法

On Error Resume Next

rs.MoveNext

If Err.Number = 5 Then

Debug.Print "记录集已关闭"

Err.Clear

Exit Do

End If

On Error GoTo 0

☆ 5、错误号-2147217900:SQL语法错误

这个错误说明你拼的SQL语句有问题,最常见的原因是用户输入里包含单引号。

vb

'错误写法

sql = "SELECT * FROM 员工表 WHERE 姓名='" & txtName.Text & "'"

'如果txtName.Text是 O'Brien,SQL就变成了 WHERE 姓名='O'Brien',单引号不配对,直接报错

'正确写法:写一个单引号过滤函数

Private Function EscapeSQL(input As String) As String

EscapeSQL = Replace(input, "'", "''")

End Function

sql = "SELECT * FROM 员工表 WHERE 姓名='" & EscapeSQL(txtName.Text) & "'"

五、错误处理的五条实战原则

☆ 1、能预防的错误别靠捕获。用户在年龄框里输入字母,你就该用KeyPress事件限制只能输入数字,而不是等出错了再弹个框。

☆ 2、关键操作一定要加错误处理。数据库的增删改、文件的读写、网络请求,这三样只要涉及外部资源,就必须加On Error。

☆ 3、错误处理里一定要写日志。弹窗用户看完就关了,但日志能帮你三天后找到问题根源。我的习惯是每个错误都记录时间、错误号、错误描述、出错位置。

☆ 4、Err.Clear要及时调用。错误处理完不Clear,后面的代码会继续沿用旧的Err对象,导致误判。

☆ 5、On Error GoTo 0要及时恢复。开了错误跳转就一直跳转,关掉才能让后面的错误正常暴露出来。

六、新手最常犯的三个错误处理误区

☆ 1、On Error Resume Next写完就忘了关。这个语句是全局生效的,你在A过程里开了,B过程里也会继续忽略错误,直到你写On Error GoTo 0才恢复。我见过有人整个模块都在静默失败,查了一天才发现是Resume Next没关。

☆ 2、错误处理里只写MsgBox,不写恢复逻辑。弹个框告诉用户出错了,然后呢?程序卡在那里,用户什么都干不了。正确做法是弹完框后,要么Exit Sub退出当前过程,要么Resume回到出错位置重试。

☆ 3、所有错误都用同一种方式处理。运行时错误和逻辑错误应该分开处理。运行时错误(数据库断开、文件不存在)需要记录日志;逻辑错误(用户输入不合法)需要提示用户重新输入。混在一起处理,排查问题会非常痛苦。

七、写在最后

VB这门语言,写功能不难,难的是写稳定。我做了这么多年VB开发,最大的感受就是:代码写得再漂亮,一崩全白搭。

错误处理不是锦上添花,是基本功。你的程序能不能在客户那里稳定跑三个月不出事,全看这套机制做得扎不扎实。

上面这套框架和处理方案,是我在二十多个项目里反复打磨出来的,不是教科书上的理论,是真正跑过生产环境的东西。拿去直接用,改改日志路径和错误提示语就行。

💡注意:本文所介绍的软件及功能均基于公开信息整理,仅供用户参考。在使用任何软件时,请务必遵守相关法律法规及软件使用协议。同时,本文不涉及任何商业推广或引流行为,仅为用户提供一个了解和使用该工具的渠道。

你在生活中时遇到了哪些问题?你是如何解决的?欢迎在评论区分享你的经验和心得!

希望这篇文章能够满足您的需求,如果您有任何修改意见或需要进一步的帮助,请随时告诉我!

感谢各位支持,可以关注我的个人主页,找到你所需要的宝贝。

博文入口:山峰哥-CSDN博客 复制到【浏览器】打开即可,宝贝入口:夸克网盘分享 宝贝:夸克网盘分享

作者郑重声明,本文内容为本人原创文章,纯净无利益纠葛,如有不妥之处,请及时联系修改或删除。诚邀各位读者秉持理性态度交流,共筑和谐讨论氛围~

📋 复制整篇文章

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/7 9:27:59

Docker 容器镜像体积分数极致裁剪:从多阶段构建、依赖包物理剥离到 Distroless 零依赖发布规范

Docker 容器镜像体积分数极致裁剪&#xff1a;从多阶段构建、依赖包物理剥离到 Distroless 零依赖发布规范在云原生与微服务架构的生产实践中&#xff0c;容器镜像的体积直接决定了集群部署的效率与系统的安全性。一个动辄几百兆甚至上吉字节&#xff08;GB&#xff09;的臃肿镜…

作者头像 李华
网站建设 2026/6/7 9:27:05

DPDK L3fwd性能测试实战:从编译到跑通你的第一个三层转发Demo

DPDK L3fwd性能测试实战&#xff1a;从编译到跑通你的第一个三层转发Demo当你第一次接触DPDK时&#xff0c;可能会被它惊人的网络包处理能力所吸引。作为数据平面开发套件&#xff0c;DPDK能够绕过操作系统内核直接操作网卡&#xff0c;实现百万级的数据包转发。而l3fwd作为DPD…

作者头像 李华
网站建设 2026/6/7 9:26:59

8个影响Python代码质量的核心事实:从执行机制到工程实践

1. 这不是又一篇“Python有多火”的口水文——8个真正影响你写代码方式的事实Python现在几乎成了编程入门的默认选项&#xff0c;但很多人学完基础语法后&#xff0c;写出来的代码还是带着其他语言的影子&#xff1a;过度嵌套、手动管理资源、绕着弯子做类型检查、把列表推导式…

作者头像 李华
网站建设 2026/6/7 9:25:11

大模型文本生成原理:从概率分布到自回归采样

1. 这不是“黑箱魔法”&#xff0c;而是一场精密的概率舞蹈你有没有盯着聊天窗口里那行刚蹦出来的文字&#xff0c;心里嘀咕&#xff1a;“它怎么知道我要说这个&#xff1f;”——别急着归功于玄学或意识觉醒。我做了三年大模型应用层开发&#xff0c;从给本地小模型喂私有数据…

作者头像 李华
网站建设 2026/6/7 9:24:44

VBA技术资料491_VBA_显示所有激活引用的GUID信息

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

作者头像 李华