【问题标题】:IFERROR with INDEX/MATCH in VBAVBA 中带有 INDEX/MATCH 的 IFERROR
【发布时间】:2016-04-16 03:29:12
【问题描述】:

我编写了以下代码,以使用索引匹配循环将外部工作表中的值带入我的工作簿。如果错误发生在索引/匹配公式中,它应该从我当前工作簿中的工作表中检索另一个值。

循环一直工作,直到它达到它应该从我当前工作簿中的工作表中引入的第一个值。

关于如何修复 IF ISERROR 循环以引入值的想法?

Sub UpdateFile()

    Dim wbMVRVFile As Workbook
    Dim wbNewMV As Workbook
    Dim wsRevFile As Worksheet
    Dim wsMvFile As Worksheet
    Dim wsMvOld As Worksheet
    Dim wsRevOld As Worksheet
    Dim wsNewMV As Worksheet
    Dim wsTempFile As Worksheet
    Dim FrRngCount As Range
    Dim i As Integer
    Dim b As Integer
    Dim y As Integer


    Set wbMVRVFile = Workbooks("Databook_2016.xlsm")

    Set wsMvOld = wbMVRVFile.Worksheets(2)
    Set wsRevOld = wbMVRVFile.Worksheets(1)
    Set wsTempFile = wbMVRVFile.Worksheets("TempFile")

    wbMVRVFile.Worksheets.Add().Name = "MV " & Format(DateSerial(Year(Date), Month(Date), 0), "dd-mm-yy")

    Set wsMvFile = wbMVRVFile.ActiveSheet

    Set FrRngCount = wsMvOld.Range("A:A")
    i = Application.WorksheetFunction.CountA(FrRngCount)

    wsTempFile.Range("A1:A" & i).Value = wsMvOld.Range("A1:A" & i).Value

    Set wbNewMV = Workbooks.Open("F:\Reports\Data\NReport" &         Format(DateSerial(Year(Date), Month(Date), 0), "yyyymmdd") & ".xls")
    Set wsNewMV = wbNewMV.Worksheets(1)

    Set FrRngCount = wsNewMV.Range("B:B")
    y = Application.WorksheetFunction.CountA(FrRngCount)

    b = i + y - 2

    wsTempFile.Range("A" & i & ":A" & b).Value = wsNewMV.Range("B2:B" & y).Value
    wsTempFile.Range("A1:A" & b).AdvancedFilter Action:=xlFilterCopy,     CopyToRange:=wsMvFile.Range("A1"), Unique:=True


    Set FrRngCount = wsMvFile.Range("A:A")
    y = Application.WorksheetFunction.CountA(FrRngCount)

    'i = 2

    For i = 2 To y

    If Not IsError(wsMvFile.Range("B" & i) = Application.WorksheetFunction.Index(wsNewMV.Range("C1:C" & Cells(Rows.Count, "C").End(xlUp).Row), Application.WorksheetFunction.Match(wsMvFile.Range("A" & i), wsNewMV.Range("B1:B" & Cells(Rows.Count, "B").End(xlUp).Row), 0), 1)) Then

    wsMvFile.Range("B" & i) = Application.WorksheetFunction.Index(wsMvOld.Range("B1:B" & Cells(Rows.Count, "C").End(xlUp).Row), Application.WorksheetFunction.Match(wsMvFile.Range("A" & i), wsMvOld.Range("A1:A" & Cells(Rows.Count, "B").End(xlUp).Row), 0), 1)

    End If

    Next i

End Sub

【问题讨论】:

  • wsMvOld.Range("B1:B" & Cells(Rows.Count, "C").End(xlUp).Row 完全是错误的。限定.Cells 父工作表。见this。

标签: vba excel


【解决方案1】:

如果继续使用这种引用范围的方法,则需要限定 Range.Cells property 的 Range.Cells property 和用于定义 Range object 的 Range.Parent property。

但是,您可以放弃该方法,转而使用更简洁的 Range.Columns 属性。

WorksheetFunction object 与严格意义上的Excel Application object 略有不同。 IsError function 对后者的响应更好,因为可以将错误携带到变体类型变量中并进行检查,而不是引发运行时错误。

Dim vrw As Variant

For i = 2 To y
    vrw = Application.Match(wsMvFile.Range("A" & i), wsNewMV.Columns(2), 0)
    If IsError(vrw) Then
        vrw = Application.Match(wsMvFile.Range("A" & i), wsMvOld.Columns(1), 0)
        If Not IsError(vrw) Then _
            wsMvFile.Range("B" & i) = Application.Index(wsMvOld.Columns(2), vrw)
    Else
        wsMvFile.Range("B" & i) = Application.Index(wsNewMV.Columns(3), vrw, 1)
    End If
Next i

这可能会受益于在循环外引用 With ... End With statement 中的一个工作表,尤其是当您在循环内重复引用但我暂时保留了所有冗余引用的内容时。

当然,您总是可以一次将公式写入所有单元格,然后将它们恢复为返回值。

【讨论】:

  • 感谢您的帮助 Jeeped。当我运行你的代码时,我得到一个编译错误“Argument not optional”。看起来它与这部分 wsMvOld.Range.Columns(1) 的范围定义有关。有什么想法吗?
  • 是wsMvOld.Columns(1) 而不是wsMvOld.Range.Columns(1)。
  • 是的,解决了它。感谢那。但是当我运行代码时,只要它应该从备份源(我当前工作簿中的工作表)检索值,它仍然会跳出循环。为什么会出现这种情况?
  • 'jumps out the loop' 告诉我它尝试处理wsMvFile.Range("A" & i),然后立即退出循环并且不尝试其他任何操作。我不明白这怎么会发生。
  • 顺便说一句,你原来的两个 worksheetfunction.index 行看着两个不同的东西。我选择了两者中的后者。也许你的意思是前者。
猜你喜欢
  • 2013-08-16
  • 2019-10-06
  • 1970-01-01
  • 2020-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-08
  • 1970-01-01
相关资源
最近更新 更多