You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VBA实现多条件查找 自动填充城市分类对应有效企业

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

Sheet1 源数据表(企业订阅记录)

Sheet1源数据

Sheet2 目标填充表

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 05:00:49