【问题标题】:Using VBA to populate a column based on matching values in two columns with a third columns value使用 VBA 根据两列中的匹配值与第三列值填充列
【发布时间】:2013-12-07 06:46:26
【问题描述】:

场景如下,我有一张有两列的工作表,一列我想匹配,另一列包含我想在匹配时复制的值。我有第二张表,其中包含要在匹配列中搜索的值以及在匹配时将值列复制到的列。

这看起来像是 VLOOKUP 的主要候选者,但我想避免对列号进行硬编码,因为数据表的内容可能会有所不同。所以我根据标题的内容查找列。如果有办法以这种灵活性对结果进行 VLOOKUP,那么这也是可行的。我不能使用公式,这需要在 VBA 中。

下面定义了 4 列:

  1. toFindCol:这包含我要尝试的值的主列表 并在 toMatch 列中找到
  2. toMatchAgainstCol:这包含我想要匹配 toFindCol 值的值列表
  3. valueCol:这包含我要复制的值,如果有匹配,该值必须来自匹配发生的行
  4. resultsCol:这是我要将值复制到的位置,需要将值复制到 toFind 值的行

由于某种原因,下面的代码给出了“类型不匹配”错误。

最终我想把它包装成一个函数/子程序,这样我就可以传入表格和列标题并让它工作,这很神奇。谁能做到这一点的布朗尼积分:)

Dim toFindCol As Range
Dim toMatchAgainstCol As Range
Dim valueCol As Range
Dim resultsCol As Range
Dim match As Variant

Set toFindCol = cohortDataSetSht.Columns(1).EntireColumn
Set toMatchAgainstCol = userSht.Cells.Find("id", , xlValues, xlWhole).EntireColumn
Set valueCol = userSht.Cells.Find("cdate", , xlValues, xlWhole).EntireColumn
Set resultsCol = cohortDataSetSht.Columns(4)

For Each findMe In toFindCol
    Set match = toMatchAgainstCol.Find(What:=findMe, LookIn:=xlValues, _
        LookAt:=xlWhole, SearchOrder:=xlByRows)

    If Not match Is Nothing Then
        resultsCol.Cells(findMe.Row, 0).Value = valueCol.Cells(match.Row, 0).Value
    End If
Next findMe

【问题讨论】:

    标签: vba excel excel-2007


    【解决方案1】:

    有一种方法可以在 VLOOKUP 中执行此操作。 vlookup的基本格式是vlookup(1,2,3,4)。

    1. 我将 A2 作为顶部单元格传递给我要查找的值。然后可以复制此公式以填充其他单元格。替换适当的单元格引用。
    2. 使用匹配功能查找要设置的列 范围在。由于我们只想要列字母(即 -“C:G”),我 使用 Len 函数,然后使用间接函数将其转换为 一个可用的范围,并对此进行查找。 INDIRECT(LEFT(ADDRESS(1,MATCH("ToMatch",$1:$1,0),4),LEN(ADDRESS(1,MATCH("ToMatch",$1:$1,0),4))-1)&":"&LEFT(ADDRESS(1,MATCH("ValueCol",$1:$1,0),4),LEN(ADDRESS(1,MATCH("ValueCol",$1:$1,0),4))-1))
    3. 然后我使用 MATCH("ValueCol",$1:$1,0)-MATCH("ToMatch",$1:$1,0)+1计算 的列号包含我们要查找的值 那个范围。
    4. 我使用 0 表示完全匹配,而不是最接近的值

    整个事情看起来像这样: =VLOOKUP(A2,INDIRECT(LEFT(ADDRESS(1,MATCH("ToMatch",$1:$1,0),4),LEN(ADDRESS(1,MATCH("ToMatch",$1:$1,0),4))-1)&":"&LEFT(ADDRESS(1,MATCH("ValueCol",$1:$1,0),4),LEN(ADDRESS(1,MATCH("ValueCol",$1:$1,0),4))-1)),MATCH("ValueCol",$1:$1,0)-MATCH("ToMatch",$1:$1,0)+1,0)

    此代码假定列标题位于第 1 行。如果不是,请将上面的 $1:$1 替换为对标题所在行的绝对引用(即 -Row 5 将是 $5:$5)。

    另一个需要注意的是,我们必须假设您要查找的值始终位于查找列的右侧。

    【讨论】:

    • 您好,很遗憾,我无法保证该值始终正确。数据转储可以根据对数据表所做的更改而更改,这些更改可能会更改列的顺序。但是,如果是这种情况(并且不在 VBA 中),答案确实有效,所以我会 +1。感谢您的回复!
    【解决方案2】:

    好的,解决了。我最终使用 Rows 作为 toFind 列:

    设置为FindCol =群组数据集Sht.Columns(1).Rows("2:" &群组数据集Sht.Columns(1).End(xlDown).Row)

    然后在比赛中我使用了这个值:

    设置匹配 = toMatchAgainstCol.Cells.Find(What:=findMe.Value2, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-18
      • 2021-02-07
      • 2020-11-26
      • 1970-01-01
      • 2021-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多