✍️ 作者:王文峰(外号:神秘小峯 / 山峯)|中国国学、传统文化与代码爱好者的程序人生,期待你的关注和支持!
vb的小脚本解决大问题:基础篇
-
- 一、开篇:小脚本解决的大问题
- 二、运行环境与第一个脚本
- 三、语法精讲:变量、运算符、流程控制
-
- [1. 变量与类型](#1. 变量与类型)
- [2. 运算符(三个高频坑)](#2. 运算符(三个高频坑))
- [3. 流程控制四件套](#3. 流程控制四件套)
- [4. 常用内置函数(字符串为王)](#4. 常用内置函数(字符串为王))
- [5. 数组:动态扩容](#5. 数组:动态扩容)
- [四、过程与函数:Sub 与 Function 的分工](#四、过程与函数:Sub 与 Function 的分工)
-
- [1. Sub vs Function(必考)](#1. Sub vs Function(必考))
- [2. 参数默认 ByRef(VBScript 第一大坑)](#2. 参数默认 ByRef(VBScript 第一大坑))
- [3. 退出与作用域](#3. 退出与作用域)
- [五、错误处理:On Error Resume Next 是唯一武器](#五、错误处理:On Error Resume Next 是唯一武器)
-
- [1. 标准姿势:出错 → 检查 → 清理](#1. 标准姿势:出错 → 检查 → 清理)
- [2. 手动抛错:Err.Raise](#2. 手动抛错:Err.Raise)
- [3. 两个必须知道的坑](#3. 两个必须知道的坑)
- [4. 统一错误处理模板(推荐收藏)](#4. 统一错误处理模板(推荐收藏))
- [六、实战:目录巡检 + 日志脚本](#六、实战:目录巡检 + 日志脚本)
- 七、避坑清单(血泪总结)
- 八、总结与自测清单
- [🎯 学习教程(传送门)](#🎯 学习教程(传送门))
- [🔥 往期文章](#🔥 往期文章)

📚 本文是「vb 的小脚本解决大问题」系列第一篇。机房里没有编译器、服务器不让装 Python、Excel 要批量处理------Windows 自带的 VBScript 就是那把瑞士军刀 :不装任何环境、双击就能跑、几十行解决一次重复劳动。这篇把语法、过程与函数、错误处理 三块基本功一次讲透,每段代码都能直接存成
.vbs运行。

一、开篇:小脚本解决的大问题
先看三个真实场景,你可能天天在手工干:
- 每天下班前把某个目录的配置文件备份一遍(手工复制改名 ×365 天);
- 月底统计 20 个服务器日志的报错行数(打开 20 个记事本数数);
- 批量修改 500 个文件的命名规则(F2 改名改到手抽筋)。
这些活儿的共同点:逻辑简单、重复量大、环境受限 。用 VBScript,一个脚本全搞定,而且 Windows 出厂自带(cscript.exe / wscript.exe),这是它至今不过时的理由。
二、运行环境与第一个脚本
两种宿主,两种体验:
| 宿主 | 行为 | 适合 |
|---|---|---|
wscript.exe |
弹窗(MsgBox)交互 | 双击运行、给非技术同事用 |
cscript //nologo xx.vbs |
控制台输出(WScript.Echo) | 调试首选,日志能落盘能重定向 |
第一个脚本(存为 hello.vbs):
vbs
' hello.vbs ------ 单引号是注释,Rem 也是
Option Explicit ' 强制声明变量,必写!防手滑第一名
Dim name
name = "王文峰"
WScript.Echo "你好," & name & "!当前时间:" & Now()
运行:cscript //nologo hello.vbs。看到输出,环境就通了。
💡
Option Explicit必须是第一条语句。它能抓住 90% 的拼写 bug(变量名写错变新变量),是 VBScript 版的"严格模式"。
三、语法精讲:变量、运算符、流程控制
1. 变量与类型
VBScript 只有一种数据类型 Variant(变体),按使用场景自动呈现子类型:
vbs
Option Explicit
Dim a, b, c
a = 100 ' 数字(Integer/Long)
b = "text" ' 字符串
c = True ' 布尔
Dim d
d = #2026-10-19# ' 日期字面量用 # 包裹
' 显式类型转换(都是函数)
WScript.Echo CStr(a), CInt("123") + 1, CDate("2026/10/19"), CDbl("3.14")
WScript.Echo TypeName(a) ' "Integer",排查类型问题很有用
2. 运算符(三个高频坑)
| 类别 | 运算符 | 坑点 |
|---|---|---|
| 字符串连接 | & |
用 & 不用 + ------"1" + 1 是 2,"1" & 1 是 "11",语义完全不同 |
| 比较 | = <> > < |
空串和 0 比较有惊喜,先 Len() 判空 |
| 模糊匹配 | Like |
支持 *、?、[a-z],If s Like "*error*" Then |
3. 流程控制四件套
vbs
' ① If 分支
Dim score
score = 85
If score >= 90 Then
WScript.Echo "优秀"
ElseIf score >= 60 Then
WScript.Echo "及格"
Else
WScript.Echo "不及格"
End If
' ② Select Case(多分支首选,比嵌套 If 清爽)
Select Case Weekday(Now())
Case 1, 7 : WScript.Echo "周末,休息"
Case Else : WScript.Echo "工作日,搬砖"
End Select
' ③ For:固定次数
Dim i, s
s = 0
For i = 1 To 10 Step 2 ' 步长 2:1,3,5,7,9
s = s + i
Next
If i > 100 Then Exit For ' 提前跳出
' ④ Do While / Do Until:条件循环(替代 While...Wend,老写法别用了)
Dim n
n = 0
Do While n < 3
n = n + 1
Loop
Do
n = n - 1
Loop Until n <= 0
' ⑤ For Each:遍历集合(数组、文件夹、字典都靠它)
Dim f
For Each f In Array(1, 2, 3)
WScript.Echo f
Next
4. 常用内置函数(字符串为王)
vbs
Dim str : str = " vbScript,好用! "
WScript.Echo Len(str) ' 长度
WScript.Echo Trim(str) ' 去首尾空格
WScript.Echo InStr(str, "Script") ' 子串位置(找不到=0)
WScript.Echo Mid(str, 3, 2) ' 截取
WScript.Echo Replace(str, "!", "。") ' 替换
WScript.Echo LCase(str) ' 转小写
' Split / Join:文本与数组的双向转换,处理 CSV/日志行的神器
Dim arr : arr = Split("a,b,c", ",")
WScript.Echo UBound(arr) ' 最大下标 = 2(注意从 0 起)
WScript.Echo Join(arr, "|") ' a|b|c
' 日期三兄弟
WScript.Echo DateAdd("d", 7, Now()) ' 加 7 天
WScript.Echo DateDiff("d", #2026-01-01#, Now()) ' 相差天数
WScript.Echo FormatDateTime(Now(), 2) ' 短日期格式
5. 数组:动态扩容
vbs
Option Explicit
Dim arr() ' 声明动态数组(不能直接用)
ReDim arr(2) ' 分配 3 个元素(0~2)
arr(0) = "甲" : arr(1) = "乙" : arr(2) = "丙"
ReDim Preserve arr(4) ' 扩到 5 个元素,**Preserve 保留原有数据**
arr(3) = "丁"
Dim item
For Each item In arr
WScript.Echo item
Next
⚠️
ReDim Preserve只能改最后一维,这是硬性限制。
四、过程与函数:Sub 与 Function 的分工
1. Sub vs Function(必考)
| 对比 | Sub(子过程) | Function(函数) |
|---|---|---|
| 返回值 | 无 | 有(通过"给函数名赋值"返回) |
| 调用方式 | Call Name(args) 或直接 Name args |
可以嵌在表达式里 x = Name(args) |
| 适合 | 执行动作:写日志、发邮件、复制文件 | 计算结果:统计、格式化、校验 |
vbs
Option Explicit
' ---- Sub:执行动作,无返回值 ----
Sub WriteHello(name)
WScript.Echo "[" & Now() & "] 你好:" & name
End Sub
' ---- Function:给函数名赋值就是返回值 ----
Function Max(a, b)
If a > b Then
Max = a ' ← 返回值靠"函数名 = 值"
Else
Max = b
End If
End Function
' ---- 调用 ----
WriteHello "王文峰" ' 简写形式
Call WriteHello("神秘小峯") ' Call 形式
WScript.Echo "较大值:" & Max(3, 9)
2. 参数默认 ByRef(VBScript 第一大坑)
vbs
Sub AddOne(ByVal n) ' ByVal:传副本,改了不影响外面
n = n + 1
End Sub
Sub AddOneRef(ByRef n) ' ByRef(默认):传引用,改外面变量
n = n + 1
End Sub
Dim x : x = 1
AddOne x : WScript.Echo x ' 1(没变)
AddOneRef x : WScript.Echo x ' 2(变了!)
💡 不写 ByVal/ByRef 就是 ByRef ------忘传
Call加括号时行为还会变。所以团队约定:参数一律显式写ByVal,除非确实要改外部变量。
3. 退出与作用域
vbs
Function FindLine(lines, keyword)
Dim i
For i = 0 To UBound(lines)
If InStr(lines(i), keyword) > 0 Then
FindLine = i
Exit Function ' 找到就走,不必跑完循环
End If
Next
FindLine = -1 ' 约定:-1 表示没找到
End Function
- 脚本级变量 (
Dim在所有 Sub 外面)全局可见,Option Explicit下全局变量各过程都能访问; - 过程级变量 (Sub/Function 内
Dim)过程结束即释放; - 没有模块/命名空间 ,大脚本靠"前缀命名"防重名:
Log_Write、Util_TrimAll。
五、错误处理:On Error Resume Next 是唯一武器
VBScript 没有 try-catch ,错误处理全靠 On Error Resume Next + Err 对象,这是本篇的重中之重。
1. 标准姿势:出错 → 检查 → 清理
vbs
Option Explicit
Dim fso, ts
Set fso = CreateObject("Scripting.FileSystemObject")
On Error Resume Next ' 出错不中断,继续执行下一行
Set ts = fso.OpenTextFile("C:\不存在\log.txt", 8, True)
If Err.Number <> 0 Then ' ← 每次 Resume Next 后必须立刻检查
WScript.Echo "写日志失败!错误号:" & Err.Number
WScript.Echo "描述:" & Err.Description
WScript.Echo "来源:" & Err.Source
Err.Clear ' 清空 Err,避免污染后续判断
WScript.Quit 1 ' 非 0 退出码,方便计划任务监控
End If
On Error GoTo 0 ' 恢复"遇错即停"的默认行为
ts.WriteLine "正常写入"
ts.Close
Err 对象三件套 :Number(错误号,0 表示无错)、Description(人话描述)、Source(出错对象/组件)。用完记得 Err.Clear。
2. 手动抛错:Err.Raise
vbs
Function LoadConfig(path)
Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FileExists(path) Then
' vbObjectError + 自定义号,避免与系统错误号冲突
Err.Raise vbObjectError + 1001, "LoadConfig", "配置文件不存在:" & path
Exit Function
End If
LoadConfig = "ok"
End Function
' 调用方统一捕获
On Error Resume Next
Dim r : r = LoadConfig("C:\app\config.ini")
If Err.Number <> 0 Then
WScript.Echo "调用失败:" & Err.Description
Err.Clear
End If
On Error GoTo 0
3. 两个必须知道的坑
- 错误处理不跨过程 :
On Error Resume Next只在当前过程内生效,每个 Sub/Function 都要自带一套"Resume Next → 检查 Err"; Resume Next会吞掉所有错 :忘记检查Err.Number,脚本会"假装成功"地跑完------这是 VBS 脚本事故的第一来源 。原则:On Error Resume Next之后紧跟If Err.Number <> 0。
4. 统一错误处理模板(推荐收藏)
vbs
Option Explicit
Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
Const LOG_PATH = "C:\logs\job.log"
Sub Log(msg)
Dim ts
Set ts = fso.OpenTextFile(LOG_PATH, 8, True) ' 8=追加模式,True=不存在则创建
ts.WriteLine FormatDateTime(Now(), 3) & " " & msg
ts.Close
End Sub
Sub HandleError(source)
Log "[ERROR][" & source & "] " & Err.Number & ":" & Err.Description
Err.Clear
End Sub
Sub DoWork()
On Error Resume Next
' ... 你的业务代码 ...
If Err.Number <> 0 Then HandleError "DoWork" : Exit Sub
On Error GoTo 0
Log "[INFO] 任务完成"
End Sub
六、实战:目录巡检 + 日志脚本
把上面三块知识拼起来------统计目录文件数、找超期文件、全程带日志,直接可用:
vbs
' patrol.vbs ------ 用法:cscript //nologo patrol.vbs D:\data 30
Option Explicit
Dim fso, folderPath, days, logFile
Set fso = CreateObject("Scripting.FileSystemObject")
' ---- 参数校验 ----
If WScript.Arguments.Count < 2 Then
WScript.Echo "用法:cscript patrol.vbs <目录> <天数>"
WScript.Quit 2
End If
folderPath = WScript.Arguments(0)
days = CInt(WScript.Arguments(1))
logFile = fso.BuildPath(fso.GetParentFolderName(folderPath), "patrol.log")
' ---- 工具函数 ----
Sub Log(msg)
Dim ts
Set ts = fso.OpenTextFile(logFile, 8, True)
ts.WriteLine FormatDateTime(Now(), 3) & " " & msg
ts.Close
End Sub
Function CountFiles(folder)
Dim f, n : n = 0
For Each f In folder.Files
n = n + 1
Next
CountFiles = n
End Function
' ---- 核心巡检 ----
Sub Patrol(folderPath, days)
On Error Resume Next
Dim folder : Set folder = fso.GetFolder(folderPath)
If Err.Number <> 0 Then
Log "[ERROR] 目录不可访问:" & folderPath & " / " & Err.Description
Err.Clear
Exit Sub
End If
On Error GoTo 0
Log "[INFO] 开始巡检:" & folderPath
Log "[INFO] 文件总数:" & CountFiles(folder)
Dim f, stale : stale = 0
For Each f In folder.Files
If DateDiff("d", f.DateLastModified, Now()) > days Then
stale = stale + 1
Log "[WARN] 超期文件:" & f.Name & "(最后修改 "
Log " " & DateDiff("d", f.DateLastModified, Now()) & " 天前)"
End If
Next
Log "[INFO] 超期文件共 " & stale & " 个,巡检结束"
WScript.Echo "巡检完成,详见 " & logFile
End Sub
Patrol folderPath, days
跑一次,日志长这样:
10:21:33 [INFO] 开始巡检:D:\data
10:21:33 [INFO] 文件总数:128
10:21:33 [WARN] 超期文件:old_backup.zip(最后修改
10:21:33 47 天前)
10:21:33 [INFO] 超期文件共 1 个,巡检结束
丢进任务计划程序每天 18:00 跑一次,一个免维护的巡检工具就有了。
七、避坑清单(血泪总结)
| 坑 | 症状 | 解法 |
|---|---|---|
忘写 Option Explicit |
变量名写错变新变量 | 永远第一行 |
用 + 连接字符串 |
"1"+1 变 2 |
一律用 & |
参数不写 ByVal |
外部变量被悄悄改掉 | 显式 ByVal |
Resume Next 后不检查 |
脚本"假装成功" | 紧跟 If Err.Number <> 0 |
| 双引号写成中文引号 | 语法错误,一脸懵 | 切英文输入法 |
| 路径反斜杠不转义 | VBS 里 \ 就是 \ |
不需要 \\(别拿 Java 习惯套) |
| 中文乱码 | 输出/日志乱码 | 文件另存为 ANSI/UTF-8 with BOM ,cscript 下用 chcp 936 |
八、总结与自测清单
- ✅
cscript //nologo是调试神器,wscript弹窗是交付神器; - ✅
Option Explicit+&连接 + 显式ByVal,三件套防住大半坑; - ✅ Sub 管"做事",Function 管"算数",返回值靠给函数名赋值;
- ✅ 字符串处理记
Split/Join/InStr/Replace四兄弟; - ✅ 错误处理唯一姿势:
On Error Resume Next→ 立刻检查Err.Number→Err.Clear→On Error GoTo 0; - ✅ 错误处理不跨过程,每个过程自带一套;
- ✅ 日志 Sub 是脚本的"保险丝",写脚本先写日志。
下一篇:《进阶篇------FSO 文件系统、字典对象 Dictionary 与 WMI 查询》------让小脚本具备真正干活的能力,敬请关注!
🎯 学习教程(传送门)
| 序号 | 专栏 | 学习内容 | 当前状态 |
|---|---|---|---|
| 01 | JAVA | 从入门到进阶的系统知识 | 持续写作中...... |
| 02 | Oracle | 数据库从用法到实战 | 创作中...... |
| 03 | vbs脚本 | 手把手教你做脚本 | 完善中...... |
| 04 | IDEA | 牛逼哄哄的编程利器 | 编写中...... |
| 05 | 面试 | 吐血整理的面试技巧 | 更新中...... |

🔥 往期文章
🧭 精选往期好文,更多请移步 我的博客主页
- 📕 HTML 入门到进阶:语义化标签、表单与多媒体
- 📗 2026 Java+AI 面试题全解析
- 📘 Spring Boot 启动流程源码解析
- 📙 Spring Boot 自动配置原理揭秘
- 📚 往期文章大全......

👍 点赞 + ⭐ 收藏 + 💬 评论,一键三连走起!
你们的支持,是我持续创作的最大动力~

✨ 以上就是今天的全部内容,关注我,技术之路不迷路!
📖 本人详解
✍️ 作者:王文峰,参与 CSDN 2020 年度博客之星评选,《Java王大师王天师》,外号:神秘小峯 / 山峯
🏮 中国国学、传统文化与代码爱好者的程序人生,期待你的关注的支持!
🔗 转载说明:务必注明来源(注明:作者:王文峰哦)