VBA实现多条件查找 自动填充城市分类对应有效企业
原有代码核心问题
- 数组读取范围错误:
inArray仅读取Sheet1前3列,后续代码访问inArray(m,4)(取消日期列)属于越界访问,无法正确判断订阅是否有效 - 循环逻辑冗余混乱:四层嵌套循环无对应业务逻辑,循环变量匹配关系错误,
Exit For跳转层级不对,根本无法匹配到正确的企业 - 输出范围定义错误:目标表包含分类1/2/3共3列需要填充,原有代码仅定义了E列单列表的输出数组,F、G列完全没有覆盖
- 判断逻辑错误:有效订阅判定条件写为
inArray(m,4) < 1,无法正确识别空值的取消日期字段 - 缺少错误兜底:如果代码运行中途报错,会导致Excel保持屏幕关闭、计算手动的状态,影响后续操作
测试数据参考
Sheet1 源数据表(企业订阅记录)

Sheet2 目标填充表

优化实现方案
采用字典+数组的实现方式,匹配效率远高于嵌套循环,适配大数据量场景,后续数据更新后直接运行即可自动刷新结果,完全符合「同城市同分类仅保留1家最新有效企业」的业务规则。
Sub CompanyLookup() Dim inWks As Worksheet, outWks As Worksheet Dim lastInRow As Long, lastOutRow As Long, lastOutCol As Long Dim inArr As Variant, outArr As Variant Dim i As Long, j As Long Dim dict As Object Dim cityKey As String, cateKey As String, fullKey As String ' 初始化字典,晚绑定无需手动加引用 Set dict = CreateObject("Scripting.Dictionary") dict.CompareMode = vbTextCompare ' 不区分文本格式差异匹配 ' 关闭Excel非必要功能提升运行速度 With Application .Calculation = xlCalculationManual .EnableEvents = False .ScreenUpdating = False .DisplayAlerts = False End With ' 错误兜底,运行出错时自动恢复Excel设置 On Error GoTo ErrHandler ' 定义工作表 Set inWks = ThisWorkbook.Sheets("Sheet1") Set outWks = ThisWorkbook.Sheets("Sheet2") ' 读取源表全量数据(A到D列,包含取消日期) lastInRow = inWks.Cells(inWks.Rows.Count, "A").End(xlUp).Row inArr = inWks.Range("A2:D" & lastInRow).Value ' 遍历源表数据,将有效企业存入字典,key为「城市|分类」 For i = 1 To UBound(inArr, 1) ' 仅处理取消日期为空的有效订阅 If IsEmpty(inArr(i, 4)) Or inArr(i, 4) = "" Then fullKey = CStr(inArr(i, 1)) & "|" & CStr(inArr(i, 3)) ' 同key直接覆盖,自动保留最新的有效企业 dict(fullKey) = inArr(i, 2) End If Next i ' 读取目标表范围 lastOutRow = outWks.Cells(outWks.Rows.Count, "D").End(xlUp).Row lastOutCol = outWks.Cells(1, outWks.Columns.Count).End(xlToLeft).Column ' 输出数组覆盖E列到最后一个分类列、第2行到最后一个城市行 outArr = outWks.Range("E2", outWks.Cells(lastOutRow, lastOutCol)).Value ' 遍历目标表每个单元格匹配对应企业 For i = 1 To UBound(outArr, 1) ' 遍历行(城市) cityKey = CStr(outWks.Cells(i + 1, "D").Value) ' 城市在D列,行号偏移1因为数组从第2行开始 For j = 1 To UBound(outArr, 2) ' 遍历列(分类) cateKey = CStr(outWks.Cells(1, j + 4).Value) ' 分类在表头第1行,列号偏移4因为从E列开始 fullKey = cityKey & "|" & cateKey ' 匹配到就写入企业名,匹配不到留空 If dict.Exists(fullKey) Then outArr(i, j) = dict(fullKey) Else outArr(i, j) = "" End If Next j Next i ' 一次性将结果写回目标表 outWks.Range("E2", outWks.Cells(lastOutRow, lastOutCol)).Value = outArr ' 恢复Excel默认设置 With Application .Calculation = xlCalculationAutomatic .EnableEvents = True .ScreenUpdating = True .DisplayAlerts = True End With ' 释放对象 Set dict = Nothing Set inWks = Nothing Set outWks = Nothing MsgBox "有效企业填充完成!", vbInformation Exit Sub ErrHandler: ' 出错时恢复Excel设置 With Application .Calculation = xlCalculationAutomatic .EnableEvents = True .ScreenUpdating = True .DisplayAlerts = True End With MsgBox "运行出错:" & Err.Description, vbCritical ' 释放对象 Set dict = Nothing Set inWks = Nothing Set outWks = Nothing End Sub
使用说明
- 打开VBA编辑器(按
Alt+F11),插入标准模块,将上述代码粘贴到模块中,按F5即可运行 - 代码自动适配数据规模,后续新增城市、新增订阅分类、更新Sheet1的订阅记录,直接运行宏即可自动刷新结果
- 全程采用内存数组+字典匹配,无逐单元格读写操作,十万行级数据也可秒级完成,不会出现卡顿
内容的提问来源于stack exchange,提问作者Christina
相关产品推荐
相关产品推荐

