【问题标题】:Find matching value row id from one workbook to another workbook从一个工作簿到另一个工作簿查找匹配的值行 ID
【发布时间】:2020-11-28 14:36:43
【问题描述】:

我有两个 Excel Book1.xlsm 和 Book2.xlsx。 Book1 将在 A 列中具有某些值,如 alpha、beta、gamma 等(无重复)。 Book2 将多次出现 Book1 值,如 beta、beta、beta、alpha、alpha、gamma、gamma、gamma、gamma、gamma等 Book2 中的值可能不会按字母顺序排序,但相同的值将组合在一起。 Book2 的值也将在 A 列中。

我在 Book1.xlsm 中设计了一个宏,它应该遍历 Book1 列 A 中的每个值,并找到 Book2 列 A 中存在相同值的第一行 id。然后应该将该行 id 复制到对应的列 B 中书 1。 这就是我的宏代码的样子。当我运行时,它会因运行时错误“1004”而失败:应用程序定义或对象定义错误

Option Explicit
Sub Get_Data()
    Dim wb1 As Worksheet
    Dim wb2 As Worksheet
    Dim wb2row As Integer
    Dim i As Integer
    Dim j As Integer
    Const A = "A"
    Const B = "B"



    Set wb1 = Workbooks("Book1.xlsm").Worksheets("Sheet1")
    Set wb2 = Workbooks("Book2.xlsx").Worksheets("Sheet1")

      'Both For loop start from row id 2.
       For i = 2 To wb1.Range("A2", wb1.Range("A2").End(xlDown)).Rows.Count
        For j = 2 To wb2.Range("A2", wb2.Range("A2").End(xlDown)).Rows.Count
  
           wb2row = Application.WorksheetFunction.Match(wb1.Cells(i, A), Range(wb2.Cells(j, A)), 0)
                    wb1.Cells(i, B).Copy (wb2.Cells(j, A))
       
            Exit For ' j loop

    
        Next j
     Next i

End Sub

【问题讨论】:

  • 你的代码有很多问题:(1)Match函数中的Range(wb2.Cells(j, A))可能是错误的原因。尝试用wb2.Range("A:A") 替换它。 (2) 如果您使用Match 函数,为什么要使用For j 循环? (3) wb1.Cells(i, B).Copy (wb2.Cells(j, A)) 不符合您概述的逻辑。你不应该改用wb1.Cells(i, B) = wb2row 吗?
  • 谢谢@SuperSymmetry 我做了你建议的改变。替换为 Range(wb2.Range("A:A")),完全移除 j 循环并替换为 wb1.Cells(i, B) = wb2row 的副本。它仍然抛出同样的错误。
  • 如果是完全同样的错误,我想不出原因。但是,如果错误是Unable to get the Match property of the WorksheetFunction class,则意味着该函数无法匹配,您必须按照@VBasic2008 的回答建议进行一些错误处理。 两个错误的编号相同 (1004)
  • 未来需要注意的另一个微妙问题:在wb1.Cells(i, B).Copy (wb2.Cells(j, A)) 行中,Copy 方法的目标位置用括号括起来。这会将范围的 传递给 Copy 方法,而不是范围本身。因此,该行与wb1.Cells(i, B).Copy wb2.Cells(j, A).Value 具有相同的效果,这将导致另一个运行时错误

标签: excel vba


【解决方案1】:

您可以让 excel 为您完成工作。试试这个(已测试)

Sub Get_Data()
  With Workbooks("Book1.xlsm").Sheets("Sheet1")
    With .Range(.Range("B2"), .Range("A" & Rows.Count).End(xlUp).Offset(0, 1))
      .Formula2 = "=IFERROR(MATCH(A2,[Book2.xlsx]Sheet1!$A:$A,0),"""")"
      .Value2 = .Value2
    End With
  End With
End Sub

【讨论】:

    【解决方案2】:

    匹配条件,返回行

    Option Explicit
    
    Sub Get_Data()
        
        ' Source
        Const srcFirst As Long = 2
        Const srcCol As String = "A"
        ' Destination
        Const dstFirst As Long = 2
        Const dstCol As String = "A"
        Const resCol As String = "B"
    
        ' Source
        Dim src As Worksheet
        Set src = Workbooks("Book2.xlsx").Worksheets("Sheet1")
        Dim rng As Range
        Set rng = src.Range(src.Cells(srcFirst, srcCol), _
            src.Cells(src.Rows.Count, srcCol).End(xlUp))
        Dim RowOffset As Long
        RowOffset = srcFirst - 1
        ' Destination
        ' 'ThisWorkbook' - the workbook containing this code.
        Dim dst As Worksheet
        Set dst = ThisWorkbook.Worksheets("Sheet1")
        
        Dim srcRow As Variant ' It could be an error value, hence 'Variant'.
        Dim i As Long
        
        For i = 2 To dst.Cells(dst.Rows.Count, dstCol).End(xlUp).Row
            srcRow = Application.Match(dst.Cells(i, dstCol), rng, 0)
            If Not IsError(srcRow) Then
                ' This will write the row.
                ' If you need index, then remove 'RowOffset'.
                dst.Cells(i, resCol).Value = srcRow + RowOffset
            Else
            ' no match found, e.g.:
                'dst.Cells(i, resCol).Value = ""
            End If
        Next i
    
    End Sub
    

    【讨论】:

    • 感谢@VBasic2008 这个解决方案也对我有用。我在原始代码中采用了您的一些解决方案,并且运行良好。在我的代码中,我将 wb2row 作为 Variant,对于 srcRow,我将其设置为 range Set rng = src.Range(src.Cells(srcFirst, srcCol), _ src.Cells(src.Rows.Count, srcCol).End(xlUp ))
    【解决方案3】:

    match函数的第二个参数必须是一个范围,而不是单个单元格。

    【讨论】:

    • 这里不是这样。 Range(wb2.Cells(j, A)) 所指的内容取决于wb2.Cells(j, A) 的值。 如果 它是一个解析为有效范围引用的字符串,那么它会很好。但似乎它根本无法解决范围引用,是这里的问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多