资讯详情

VBA编程练习题+近年真题高效刷题指南:从Range到字典的实战拆解

📅 2026/10/17 19:58:35 | 华诺云谱 👁 阅读
VBA编程练习题+近年真题高效刷题指南:从Range到字典的实战拆解
简介这份VBA编程练习题与近年真题文档面向正在学习或备考VBA的Office用户、计算机二级考生及办公自动化爱好者帮助其通过真题演练掌握语法要点与常见考点。资源共1个doc文件压缩包约780KB内容以题目与解析为主涵盖Do Until、Do Loop While等循环结构Select Case多分支选择ByVal与ByRef参数传递差异以及DAO、ADO数据访问对象等核心概念。文档中每道题均配有答案与思路说明例如循环终止条件填写、字符串长度计算、星号图形输出、双精度类型标识等便于读者对照练习、查漏补缺。目前已有1810人学习下载适合需要系统刷题、巩固VBA基础并提升实际编程能力的读者使用。1. 从一份“vba编程练习题近年真题.doc”说起为什么刷题总在同一个坑里翻车很多人拿到一份“vba编程练习题近年真题.doc”第一反应是打开 Word 从头刷到尾把每道题的答案敲进 VBE 里跑一遍跑通了就翻页。三个月后回头再看同样的单元格遍历题还是写不利索同样的字典去重题还是要在For Each里卡半天。问题不在题量而在于这份文档本质上是题目清单不是能力地图——它把 Range、数组、字典、正则、事件、窗体这些考点平铺在一起却没有告诉你哪些题在练同一块肌肉哪些题只是换了个壳。VBA 这门语言有个特点语法糖少、对象模型重、调试手段原始。它不像 Python 那样有丰富的第三方库兜底很多需求必须靠Range、Array、Dictionary、FileSystemObject这几个老伙计硬扛。所以刷练习题的正确姿势不是按文档顺序刷而是按对象模型分层刷先练单元格读写再练数组与字典的批量处理最后练事件与窗体这类交互层。近年真题的命题趋势也很明显——纯语法题在减少结合业务场景的综合题在增加比如“按部门汇总销售数据并生成透视表”“从多张工作表提取不重复客户名单”。这篇文章面向两类人一类是刚接手 VBA 维护工作、需要快速把零散知识串成体系的新手另一类是刷了不少题但遇到真实需求还是无从下手的熟手。我会把这份文档拆成可执行的训练路径给出每类题型的标准解法模板、参数设置和排错方法最后落到一个能直接套用的“真题拆解框架”上。不堆题只讲怎么把题刷出复利。2. 把练习题按对象模型分层Range、数组、字典、正则各练什么2.1 先分清四类题型的训练目标拿到一份练习题文档我一般先花十分钟做一次快速分类而不是直接开刷。分类的依据是这道题的核心操作落在哪个对象上。VBA 里高频对象就那么几个每类对象对应一组固定的思维模式题型类别典型题干关键词核心对象训练目标单元格操作遍历、填充、条件格式、查找Range / Cells熟悉定位与批量读写数组处理拆分、合并、排序、转置Array / Variant()减少与工作表的交互次数字典去重不重复、统计、分组、匹配Dictionary用键值对替代循环嵌套文本解析提取、替换、校验、拆分RegExp / Split处理非结构化字符串这个分类不是学术分类是刷题顺序分类。Range 题练的是“怎么少读写”数组题练的是“怎么在内存里算完再写回”字典题练的是“怎么把 O(n²) 降成 O(n)”正则题练的是“怎么用模式匹配替代一堆 If”。四类题的难度是递进的但很多文档把它们混在一起导致新手在 Range 还没练熟的时候就被字典题劝退。我通常建议按“Range → 数组 → 字典 → 正则”的顺序刷每类先刷 5 道基础题再刷 3 道综合题。基础题的目的是形成肌肉记忆综合题的目的是练组合。比如 Range 基础题就是“把 A 列所有空单元格填上 0”综合题就是“找出 A 列中满足 B 列条件的单元格并高亮”。2.2 Range 题先练“少读写”再练“准定位”Range 类题目最容易犯的错是在循环里频繁读写单元格。下面这段代码是典型的反面教材也是练习题里最常见的“遍历 A 列并修改”题型 反面写法每次循环都读写工作表1000 行就要 2000 次交互 Sub BadLoop() Dim i As Long For i 1 To 1000 If Cells(i, 1).Value Then Cells(i, 2).Value Cells(i, 1).Value * 2 End If Next i End Sub这段代码逻辑没错但性能极差。工作表交互是 VBA 里最慢的操作之一1000 行还能忍10000 行就要等好几秒。正确的做法是一次性读入数组在内存里处理再一次性写回 正面写法一次读、一次算、一次写 Sub GoodLoop() Dim arr As Variant Dim i As Long 一次性把 A1:B1000 读入内存数组 arr Range(A1:B1000).Value For i 1 To UBound(arr, 1) If arr(i, 1) Then arr(i, 2) arr(i, 1) * 2 End If Next i 一次性写回 Range(A1:B1000).Value arr End Sub这里的关键参数是Range(A1:B1000).Value它返回一个二维 Variant 数组下标从 1 开始。UBound(arr, 1)取第一维上界也就是行数。注意数组下标和单元格行号在这里是对齐的不需要额外偏移。如果题目要求处理动态行数可以用Cells(Rows.Count, 1).End(xlUp).Row先算出最后一行再拼 Range 地址。Range 题里还有一个高频考点是定位Find、AutoFilter、SpecialCells。练习题里常出现“找出所有包含‘异常’的单元格并标红”新手容易写成For Each加InStr熟手会直接用AutoFilter或Find。这两种写法的差距在数据量上万时非常明显。我一般建议单条件查找用Find多条件筛选用AutoFilter空值/公式/常量定位用SpecialCells。2.3 数组与字典题把嵌套循环换成键值查找数组和字典类题目是练习题文档里的重头戏也是近年真题区分度最高的部分。典型题干是“统计每个部门的人数”“找出两张表都出现的客户”“按月份汇总金额”。新手解法通常是双重循环 新手解法双重循环O(n²) Sub CountDeptBad() Dim i As Long, j As Long Dim dept As String Dim cnt As Long For i 2 To 1000 dept Cells(i, 1).Value cnt 0 For j 2 To 1000 If Cells(j, 1).Value dept Then cnt cnt 1 Next j Cells(i, 2).Value cnt Next i End Sub这段代码在 1000 行时还能跑10000 行就要几分钟。用字典改写后复杂度降到 O(n) 熟手解法字典一次遍历O(n) Sub CountDeptGood() Dim dict As Object Dim arr As Variant Dim i As Long Dim dept As String Set dict CreateObject(Scripting.Dictionary) arr Range(A2:A1000).Value 第一遍统计 For i 1 To UBound(arr, 1) dept arr(i, 1) If dept Then If dict.Exists(dept) Then dict(dept) dict(dept) 1 Else dict(dept) 1 End If End If Next i 第二遍写回 For i 1 To UBound(arr, 1) dept arr(i, 1) If dept Then Cells(i 1, 2).Value dict(dept) End If Next i End Sub这里有两个参数值得注意CreateObject(Scripting.Dictionary)是后期绑定不需要在 VBE 里手动引用库适合分发给别人用dict.Exists(key)判断键是否存在比On Error Resume Next那种写法干净得多。字典的Keys和Items方法可以一次性取出所有键和值配合Application.Transpose可以直接写回一列。数组题里另一个高频考点是动态数组的 ReDim。练习题里常出现“把满足条件的行提取到新数组”新手容易用ReDim Preserve在循环里反复扩容性能很差。正确做法是先ReDim一个足够大的数组用一个计数器记录实际长度最后再ReDim Preserve一次裁切。这个技巧在真题里反复出现值得单独练几遍。2.4 正则题用模式匹配替代字符串拼接正则类题目在练习题文档里占比不高但在近年真题里出现频率在上升尤其是数据清洗场景。典型题干是“从混合文本中提取手机号”“校验身份证格式”“把多个空格替换成一个”。VBA 里用正则需要引用Microsoft VBScript Regular Expressions 5.5或者用后期绑定CreateObject(VBScript.RegExp)。 提取 A 列文本中的所有 11 位数字串 Sub ExtractPhone() Dim reg As Object Dim arr As Variant Dim i As Long Dim matches As Object Set reg CreateObject(VBScript.RegExp) reg.Global True 全局匹配不只找第一个 reg.IgnoreCase True 忽略大小写 reg.Pattern \d{11} 11 位连续数字 arr Range(A1:A100).Value For i 1 To UBound(arr, 1) If reg.Test(arr(i, 1)) Then Set matches reg.Execute(arr(i, 1)) Cells(i, 2).Value matches(0).Value End If Next i End Sub三个参数必须显式设置Global决定是否匹配所有结果IgnoreCase决定是否忽略大小写Pattern是模式串。reg.Test只返回布尔值适合做校验reg.Execute返回匹配集合适合做提取。matches(0).Value取第一个匹配项如果要取所有匹配项需要遍历matches集合。正则题最容易翻车的地方是模式串写错但不报错。比如\d{11}写成\d{11,}匹配结果会多出很多。我一般建议先在草稿里用几组测试数据验证模式串再写进代码。另外 VBA 的正则不支持某些高级语法比如命名捕获组遇到复杂需求要拆成多步处理。3. 近年真题的命题套路从“语法题”到“业务综合题”的拆解方法3.1 真题的三层结构数据层、逻辑层、输出层近年真题和早期练习题最大的区别是场景化。早期题目直接说“用字典统计”近年题目会说“某公司有一份销售流水请按区域汇总并生成报表”。表面上看是加了业务背景实际上命题结构没变还是三层数据层数据在哪、什么格式、有没有脏数据逻辑层要做什么计算、按什么维度分组、有没有优先级输出层结果写到哪里、什么格式、要不要排序拆题的时候我习惯先把题干里的这三层信息标出来。比如“从 Sheet1 的 A 到 D 列读取订单数据按客户名称汇总金额结果写入 Sheet2 并从高到低排序”——数据层是 Sheet1 的 A:D逻辑层是按客户汇总金额输出层是 Sheet2 加降序。三层拆清楚后代码结构自然就出来了读数据 → 字典汇总 → 数组排序 → 写回。这个拆解方法能解决大部分“看到题不知道从哪下手”的问题。很多新手卡住不是因为不会写代码而是因为没把题干翻译成对象操作。我一般建议在草稿纸上画一个三栏表左边写数据来源中间写处理逻辑右边写输出目标填完再动手。3.2 综合题的代码骨架一个可复用的四段式模板综合题不管题干怎么变代码骨架基本是固定的四段读入 → 处理 → 排序 → 输出。下面这个模板可以直接套用到大部分汇总类真题Sub SummaryTemplate() Dim arr As Variant Dim dict As Object Dim i As Long, n As Long Dim key As String Dim result() As Variant Dim temp As Variant 第一段读入数据到数组 arr Range(A2:D Cells(Rows.Count, 1).End(xlUp).Row).Value 第二段字典汇总 Set dict CreateObject(Scripting.Dictionary) For i 1 To UBound(arr, 1) key arr(i, 1) 假设第一列是分组键 If dict.Exists(key) Then dict(key) dict(key) arr(i, 4) 假设第四列是金额 Else dict(key) arr(i, 4) End If Next i 第三段转成二维数组并排序 n dict.Count ReDim result(1 To n, 1 To 2) Dim keys As Variant keys dict.Keys For i 0 To n - 1 result(i 1, 1) keys(i) result(i 1, 2) dict(keys(i)) Next i 冒泡排序按第二列降序 Dim j As Long For i 1 To n - 1 For j i 1 To n If result(j, 2) result(i, 2) Then temp result(i, 1): result(i, 1) result(j, 1): result(j, 1) temp temp result(i, 2): result(i, 2) result(j, 2): result(j, 2) temp End If Next j Next i 第四段写回工作表 Range(F2).Resize(n, 2).Value result End Sub这个模板里几个参数需要根据题目调整Range(A2:D ...)的列范围、arr(i, 1)的分组键列号、arr(i, 4)的数值列号、Range(F2)的输出起点。排序部分用的是冒泡数据量小的时候够用上万行建议换成ArrayList的Sort或者写个快速排序。注意dict.Keys返回的是 0 基数组所以循环从 0 到 n-1写回时下标加 1。这个骨架的价值在于把综合题拆成了填空题。刷真题的时候每道题只需要改几个参数不用每次从零开始想结构。练到后面看到题干就能直接反应出这四段分别对应什么。3.3 真题里最容易失分的三个细节近年真题的评分点往往不在主逻辑上而在几个细节上。我统计过一批模拟题的失分情况排前三的是第一没有处理空值和错误值。题干里说“数据可能不完整”很多人直接arr(i, 1)就参与计算遇到空值就报错。正确做法是在读入后加一层判断或者用IsError检查。这个细节在真题里几乎每年都考。第二输出没有清空旧数据。如果 Sheet2 之前有数据直接Resize写回会留下残留。我一般会在写回前加一句Range(F2).CurrentRegion.ClearContents或者用UsedRange判断。这个坑在模拟环境里不明显真实场景里很常见。第三字典的键没有做类型统一。比如客户名称有的带空格有的不带有的数字存成文本有的存成数值字典会当成不同的键。处理方法是读入后统一Trim和CStr或者用UCase统一大小写。这个细节在真题里经常作为“隐藏考点”出现。4. 避坑与排查刷 VBA 练习题时最常见的五类翻车4.1 现象代码在 VBE 里跑得好好的换个文件就报错原因引用了特定库或依赖了特定工作表名。比如用了Dictionary的早期绑定需要在 VBE 里手动勾选Microsoft Scripting Runtime或者代码里硬编码了Sheets(Sheet1)换文件后工作表名变了。解决统一用后期绑定CreateObject(Scripting.Dictionary)避免库引用问题。工作表引用改用ThisWorkbook.Sheets(1)或ActiveSheet或者用Sheets集合的索引。如果必须用名称加一个On Error兜底提示用户检查工作表名。4.2 现象循环跑得越来越慢最后卡死原因在循环里频繁读写单元格或者ReDim Preserve在循环里反复扩容。前者是工作表交互开销后者是内存拷贝开销。解决读写改批量用数组做中转。ReDim Preserve只在最后裁切时用一次中间用计数器记录实际长度。如果数据量超过 10 万行考虑用ADODB或者QueryTable直接查不要用 VBA 循环硬扛。4.3 现象正则匹配结果和预期不一致但代码不报错原因模式串写错或者Global属性没设。比如\d{11}写成\d{11,}或者忘了reg.Global True导致只匹配第一个。解决先在草稿里用几组测试数据验证模式串确认匹配范围。Global、IgnoreCase、MultiLine三个属性根据需求显式设置。VBA 正则不支持命名捕获组和零宽断言的部分语法复杂需求拆成多步。4.4 现象字典统计结果少了几个键原因键的类型不一致。比如“北京”和“北京 ”带空格被当成两个键或者数字 100 和文本 100 被当成两个键。解决读入后统一处理key Trim(CStr(arr(i, 1)))需要忽略大小写就加UCase。如果键是数字统一转成CDbl或CLng。这个坑在真实数据里非常常见练习题里往往不体现但真题里经常考。4.5 现象排序结果不对或者排序后数据错位原因排序时只交换了一列没有同步交换关联列。比如按金额排序时只换了金额列客户名称没跟着换导致数据错位。解决排序时用临时变量同时交换所有关联列或者把整行作为一个整体交换。数据量大时不要用冒泡改用ArrayList的Sort配合自定义比较器或者把数据写到工作表后用Range.Sort排完再读回数组。5. 把真题刷出复利一个可复用的拆解框架与验证习惯刷题刷到最后拼的不是题量是拆解速度和验证习惯。我自己的做法是维护一个“题型-模板”对照表每刷一道新题先判断它属于哪类题型然后直接调用对应的模板骨架只改参数不重写结构。这个习惯让我的刷题效率在两个月内翻了一倍因为大部分题目的 80% 代码是重复的。具体来说我会把常见题型归纳成六个模板单元格遍历模板、数组批量处理模板、字典汇总模板、字典去重模板、正则提取模板、综合汇总模板。每刷一道新题先归类再套模板最后只关注题目特有的那 20% 逻辑。比如“按部门汇总销售额”和“按区域汇总订单量”本质是同一个模板只是分组键和数值列不同。验证习惯方面我坚持三个动作第一用边界数据测试比如空值、单行、全重复、全不重复第二对比手工结果取前 10 行用 Excel 公式算一遍和代码结果比对第三记录翻车点每道题跑通后写一行注释说明这道题最容易错的地方。这个习惯坚持三个月后我发现自己对真题的“隐藏考点”越来越敏感看到题干就能猜到出题人想考什么。最后一个技巧是关于真题的二次利用。很多人刷完一遍就把文档扔了我一般会做两件事一是把每道题的代码骨架提取出来存到一个单独的模块里标注题型和关键参数二是把题干改一改比如把“按部门汇总”改成“按月份汇总”把“降序”改成“升序”自己给自己出变体题。这个过程能逼着你理解模板的边界而不是死记代码。我自己的教训是早期刷题追求“跑通就行”结果遇到变体题就卡壳。后来强迫自己每道题都写注释、做变体、记翻车点虽然刷题速度慢了但真实需求来的时候能直接上手。VBA 这门语言语法一周就能学完剩下的时间都是在练“怎么把业务翻译成对象操作”。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑