如何从 For Each 循环中任何给定 'i' 的 Offset.Value 中减去 .Value?

How does one subtract the .Value from the Offset.Value of any given 'i' in a For Each loop?

我在VBA中编写了以下代码:

For Each W In Range("B5:B15000").Cells
    If W.Offset(-1, 0).Value - W.Value > 1.5 Then
        W.Offset(-1, 0).EntireRow.Delete
    End If
Next W

目的是在第 5 行和第 15000 行之间向下迭代 'Column B',从偏移 'W' 值中减去每个当前 'W' 值。如果方程式的结果差值大于 1.5,则删除整个 'W'(Offset) 行。如果差异小于或等于 1.5,则继续下一个 'W'。

为了更好地理解数据集,B列本质上是一个时间戳序列。当您进一步向下移动该列时,时间戳会以不同的秒数增加。我需要找出大于 1.5 秒的间隙(可以这么说)并将其删除。

这是列数据的示例:

任务看起来很简单,但我收到 'Type Mismatch' 错误。我对 For Each 循环比较陌生,所以不太了解哪些部分不匹配。

类型不匹配 错误是由于值不是您认为的类型。最有可能的是,其中一个单元格是空白的,或者包含文本,或者不是数字的内容。

使用 CDbl 显式转换为 Double 可能无法修复 类型不匹配 错误,因为如果任一值不 一个数字,无论如何事情都会变得繁荣 - 隐式转换与否。

正确的做法是处理所有边缘情况 - 您需要决定如何处理 不是数字 的值 - 这是一个将它们视为 0:

Private Function GetNumericValue(rng As Range) As Double
    Dim result As Double
    On Error Resume Next
    result = CDbl(rng.Value)
    If Err.Number <> 0 Then result = 0
    On Error GoTo 0
    GetNumericValue = result
End Function

现在你可以这样做了:

If GetNumericValue(W.Offset(-1, 0)) - GetNumericValue(W.Value) > 1.5 Then

如果仍然不能解决问题,并且您的数据完全由 似乎是 数字组成,那么我的赌注是 小数分隔符 角色关闭。在控制面板/区域设置中验证。您的电子表格似乎需要一个点,但您的设置可能将其作为逗号。

格式肯定是数字,所以你应该不会出现类型不匹配的情况。我的猜测是第 5 行是包含数据的第一行,因此将 -1 偏移到第 4 行会导致错误,因为您不能减去字符串(header 文本)和数字。

除此之外,您的自上而下逻辑可能会出现问题(此外还有删除迭代器 W、修改 collection 的实现问题)。考虑以下数据:

  1. 12
  2. 13
  3. 15
  4. 16
  5. 17

自上而下会删除第 3 行,然后将第 4 行与第 2 行进行比较(因为第 3 行已被删除)并删除它很好,因为差异大于 1.5(依此类推)。

相反,您会想要自下而上。在上面的示例中,第 5 行和第 4 行将保留,因为它们将根据其预期值进行比较,而第 3 行仍被删除。

该代码可能如下所示:

Dim i As Long
For i = 15000 to 6 Step -1 '6 because 6-1 would mean 5 is the first row which contains data.
    If Cells(i - 1, "B").Value - Cells(i, "B").Value > 1.5 Then
        Rows(i).Delete
    End If
Next

编辑:自下而上仍然会在您的数据中留下很大的差距。例如,在您提供的数据中,将删除以下(除其他外):

  • 50
  • 31
  • 23