在 Excel VBA 中查找基于 2 列的数据

Jac*_*yOL 5 excel vba

在此输入图像描述
在此输入图像描述

如 2 张图片所示,有 2 张。“结果”是我希望结果所在的工作表,“来自”工作表是搜索的来源。基本上,我想根据“班级编号”和“学生编号”搜索该学生的姓名。“班级编号”和“学生编号”都不是唯一的,这意味着可能存在重复。但“班级号”和“学号”的组合是唯一的,这意味着每个学生都会有不同的“班级号”和“学号”组合。所以我想到的方法是首先创建一个支撑列,将“班级编号”和“学号”连接起来,然后进行VlookUp。代码如下:

Sub vlookupName()
    
    'get the last row of both sheets
    resultRow = Sheets("Result").[a1].CurrentRegion.Rows.Count
    fromRow = Sheets("From").[a1].CurrentRegion.Rows.Count
    
    'concat Class number and student number to get a unique string used for vlookup
    Sheets("Result").Range("D2:D" & resultRow) = "=B2 & C2"
    Sheets("From").Columns("A").Insert
    Sheets("From").Range("A2:A" & resultRow) = "=c2 & d2"
    
    'vlookup
    Sheets("Result").Range("A2:A" & resultRow) = Application.VLookup(Sheets("Result").Range("D2:D" & resultRow).Value, _
        Sheets("From").Range("a2:b" & fromRow).Value, 2, False)
        
    '(delete columns to get back to raw file for next test)
    Sheets("Result").Columns("D").Delete
    Sheets("From").Columns("A").Delete
    Sheets("Result").Range("A2:A" & resultRow) = ""
End Sub

Run Code Online (Sandbox Code Playgroud)

对代码或方法的任何部分的改进表示赞赏。

Cri*_*use 8

当尝试查找多个值时,连接是危险的。考虑以下两种情况:

班级编号 学生号码
1 15
11 5

两个串联都会得到115,而且这并不唯一。

您可能会说添加分隔符可以解决这个问题。像下划线这样的东西和上面的两个例子将变成1_1511_5。是的,只要你的部分是数字,那就可以了,但如果它们是文本呢?就像是:

第1部分 第2部分
1_ 5
1 _5

两种连接都会得到1__5,而且这也不是唯一的。虽然最后一个例子是被迫的,但我希望它能证明这种方法不干净并且可能导致错误的结果。

根据 2 个图像中显示的范围,我将在结果表的单元格A2中写入以下公式:

=INDEX(From!$A$2:$A$11,MATCH(1,INDEX((From!$B$2:$B$11=$B2)*(From!$C$2:$C$11=$C2),0),0))

或者用更英语的方式:

=INDEX(ResultRange,MATCH(1,INDEX((KeyPart1Range=DesiredPart1)*(KeyPart2Range=DesiredPart2),0),0)) 可以通过添加第 3 部分、第 4 部分等轻松扩展它,以匹配所需的多个条件。

逻辑很简单:

  1. 类似的东西From!$B$2:$B$11=$B2会返回一个布尔值数组(TRUE和),对应于范围FALSE内的行数From!$B$2:$B$11
  2. 将两个(或更多)布尔值数组相乘将得到一个由 1 和 0 组成的数组,其中 1 表示TRUE,0 表示FALSE
  3. INDEX(array,0)返回完整数组,无需按 Ctrl+Shift+Enter(非 Office 365 的 Excel 版本需要)
  4. MATCH(1,...)返回满足所有指定条件的行索引
  5. 最外面INDEX返回想要的结果

为什么要运行 VBA 代码来重新创建可以直接在 Excel 中完成的公式?它通常会“闻到”不良做法的“味道”。这种方法使得整个项目的可维护性变得更加困难。如果重命名工作表,则需要更新代码。如果更改范围(例如插入列),则需要更新代码。这样的例子不胜枚举。

假设您不希望最终结果选项卡中出现公式,那么为什么不创建一个中间表来执行您想要的所有公式(Excel 公式),然后您的代码可以简单地复制粘贴到最终结果选项卡中将只是价值观。这样,如果您需要添加额外的逻辑,您可以只在纯 Excel 中处理中间工作表,而不必担心同步任何代码。


Tim*_*ams 4

这不是一个 VBA 答案,但值得注意的是,有一个 MATCH() 的“多列”版本,可以在此处使用:

在此输入图像描述