【问题标题】:Index(Match()) in VBA Excel with Formulas in CellsVBA Excel中的索引(匹配())与单元格中的公式
【发布时间】:2018-08-09 02:16:36
【问题描述】:

第一次来。一般来说,编码很新。这样做只是为了好玩/尝试学习。提前感谢您的帮助。

我试图让我的代码查看一个 CSV 单元格并将值提取到一个数组中。然后,使用该数组 Index(Match()) 将最后一列中的日期放入一个新数组中。然后我会查看最新日期并将其写入 CSV 单元格旁边的单元格中。

这是我目前所拥有的:

Dim DepArray As Variant, FinArray As Variant, x As Integer, i As Integer, y As Variant, StartDate As Date
    DepArray = Split(Target, ",")
    x = UBound(DepArray)
    'INDEX(MATCH()) to write to new array of finish dates for prior tasks
    For i = 0 To x
        y = Application.WorksheetFunction.Index(Sheets("SH1").Range("A1:E4").Value, Application.Match(DepArray(i), Sheets("SH1").Range("A1:A4").Value, 0), 5)
        FinArray(i) = y
    Next i
    StartDate = Application.WorksheetFunction.Max(FinArray)
    Target.Offset(0, 1).Value = StartDate

我在 y=Index(Match()) 行上遇到类型不匹配错误。我认为,我已经尝试了每种变量类型,将 y 或者声明为整数和日期。有什么想法吗?

仅供参考,我正在使用 .Value 标注,因为在 A 列和 E 列中,项目编号和日期都是由单元格中的函数引入的。

另外,如果您有清理代码的提示或发现我还没有解决的其他问题,我很乐意学习更好的做法。

谢谢!

更新了代码以帮助检查。我想我得到了 Match(),因为现在错误显示在 MsgBox y(i) 线上。我也试过作为 MsgBox y

Private Sub Worksheet_Change(ByVal Target As Range)

If Not Intersect(Target, Range("B1:B4")) Is Nothing Then
    Dim DepArray As Variant, FinArray As Variant, x As Integer, i As Integer, y As Variant, StartDate As Date
    DepArray = Split(Target, ",")
    MsgBox DepArray(0)
    x = UBound(DepArray)
    MsgBox x
    MsgBox DepArray(x)
    'INDEX(MATCH()) to write to new array of finish dates for prior tasks
    For i = 0 To x
        MsgBox DepArray(i)
        y = Application.Match(DepArray(i), Sheets("Sheet1").Range("A1:A4").Value, 0)
        MsgBox y(i)
        'FinArray(i) = Application.WorksheetFunction.Index(Sheets("Sheet1").Range("A1:E4").Value, Application.Match(DepArray(i), Sheets("Sheet1").Range("A1:A4").Value, 0), 5)

    Next i
    StartDate = Application.WorksheetFunction.Max(FinArray)
    Target.Offset(0, 1).Value = StartDate
End If


End Sub

【问题讨论】:

  • 这些列中是否存在工作表错误(例如#N/a、#DIV/0! 等)? (F5,特殊,错误)
  • 也许试试Sheets("SH1").Range("A1:E4") 没有.Value 似乎这可能更容易实现为Vlookup?在填充之前,您还需要标注 FinArray()
  • 感谢收看!我在工作表上没有任何错误。该代码还不足以修改任何单元格值。我认为 FinArray 的 Dimensioned 与 DepArray 相同吗?请参阅暗线。我更喜欢在我的电子表格上通常使用 Index(Match())。即使在这种情况下使用 Vlookup 可以更轻松地完成,我也想学习如何在 VBA 中正确执行 Index(Match())。再次感谢
  • 我认为我得到了 Match(),因为现在错误显示在 MsgBox y(i) 行上,这是因为 y 不是数组。 Match 函数返回一个变体,但只有一个值。 MsgBox y 应该工作,除非 Match 返回错误值。您可以在该行上设置一个断点并在 VBE 的 Locals 窗口中查看 y

标签: vba excel


【解决方案1】:

这一行将DepArray 创建为一个字符串数组:

DepArray = Split(Target, ",")

因为Split返回一个字符串数组。

稍后,当你这样做时:

y = Application.Match(DepArray(i), Sheets("Sheet1").Range("A1:A4").Value, 0)

Match 函数返回 1004 错误,因为该范围内没有 "1" 的值,而是 1 的值!

您可能可以通过转换为 long/integer 来解决:

Dim valueToMatch as Long
valueToMatch = CLng(DepArray(i))
y = Application.Match(valueToMatch, Sheets("Sheet1").Range("A1:A4").Value, 0)

捕获错误通常也是一个好主意,例如:

If IsError(y) Then
    MsgBox "Unable to find " & CStr(valueToMatch)
    ' Exit sub, or go to next iteration, etc.
End If

你还需要ReDimFinArray,在这行之后:

x = UBound(DepArray)
ReDim FinArray(x)

并取消注释将值分配给此数组的行,否则它仍然是Empty 变体,并且Max(Empty) 每次都会返回0:D

另外,您需要在程序开始时执行Application.EnableEvents = False,然后在程序结束时执行Application.EnableEvents = True,以避免可能的无限循环,因为Target.Offset(0, 1).Value = StartDate 将触发Change 事件: )

【讨论】:

  • 谢谢,大卫。我想我们很接近了!我实际上选择使用 CDbl,因为 Index() 函数查找参数 2 的 Double 类型。当 FinArray(i) 显示时,我在框中得到了正确的值:FinArray(i) = Application.WorksheetFunction.Index(Sheets("Sheet1").Range("A1:E4").Value, y, 5) MsgBox FinArray(i) 但是,无论我如何更改值到或如何设置单元格格式我在单元格中输出时得到 12:00:00 AM:StartDate = Application.WorksheetFunction.Max(FinArray) Target.Offset(0, 1).Value = StartDate StartDate 被标注为日期
  • @Gabba48 在该行设置断点,然后使用 Locals 窗口检查 StartDate 的实际值?它显示了什么?
  • 好的等等。我想我能得到这个。 Max(FinArray) 处于最大位置,而不是最大值。所以它在数组中的最后一个位置被初始化为 0 或其他东西。
  • 看来你没有正确标注FinArray,让我再看一遍……
  • 是的,就是这样。 FinArray 被声明为 Variant,它从未分配任何值。它不是一个数组,它是一个空变量,所以它的值是0