VBA向ArrayList添加元素时已有元素被覆盖、最终数量不足问题求解
问题复现逻辑
你遇到的元素覆盖、数量不足的问题,本质是两个VBA特性叠加了错误的变量清空逻辑导致的:
1. Range遍历顺序不符合预期
VBA中使用For Each遍历多列区域时,默认遵循列优先规则:你定义的Range("B7:C1000")不会逐行遍历B7→C7→B8→C8…,而是先遍历完B列的所有单元格B7→B8→B9→…→B1000,再开始遍历C列的所有单元格C7→C8→C9→…→C1000。
2. 变量清空逻辑打断了跨列取值链路
你原本的代码如下:
Set Rng = Range("B7:C1000") Set dateNtimes = CreateObject("System.Collections.ArrayList") For Each c In Rng If Len(c) > 0 Then If c.Row Mod 2 = 1 Then datev = c ElseIf c.Row Mod 2 = 0 Then timev = c End If If Len(datev) > 0 And Len(timev) > 0 Then dateNtime = datev & timev dateNtimes.Add dateNtime datev = "" timev = "" End If End If Next c
代码中每次成功添加元素后,都会同时清空datev和timev,执行逻辑如下:
- 遍历B列奇数行:给
datev赋值,此时timev为空,不触发添加逻辑 - 遍历B列偶数行:给
timev赋值,两个变量都有值,拼接后添加到ArrayList,随后立刻清空datev和timev - 整个B列遍历完成后,B列的所有奇偶行已经凑出了一半的有效元素,但是所有
datev都已经被清空 - 开始遍历C列时,即使遇到匹配的奇偶行值,也没有对应的
datev可以拼接,因此C列的值几乎全部浪费,最终只有一半的元素
当你移除datev = ""后,B列遍历阶段赋值的datev不会被清空,后续遍历C列的对应行时,就可以和保留的datev匹配,生成完整的有效元素,列表元素数量就符合预期了。
优化建议
如果你的需求本来就是按行匹配两列的取值,建议直接改为按行遍历的写法,从根源上避免列优先遍历的坑:
Set Rng = Range("B7:C1000") Set dateNtimes = CreateObject("System.Collections.ArrayList") Dim rowIdx As Long For rowIdx = 1 To Rng.Rows.Count datev = Rng.Cells(rowIdx, 1) timev = Rng.Cells(rowIdx, 2) If Len(datev) > 0 And Len(timev) > 0 Then dateNtimes.Add datev & timev End If Next rowIdx
内容的提问来源于stack exchange,提问作者kidd
相关产品推荐
相关产品推荐

