【问题标题】:How does one subtract the .Value from the Offset.Value of any given 'i' in a For Each loop?如何从 For Each 循环中任何给定“i”的 Offset.Value 中减去 .Value?
【发布时间】:2015-09-21 17:07:00
【问题描述】:

我有以下用 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 行之间的“B 列”,从偏移“W”值中减去每个当前“W”值。如果等式的结果差大于 1.5,则删除后面的整个“W”(偏移)行。如果差值小于或等于 1.5,则继续下一个“W”。

为了更好地理解数据集,B 列本质上是一个时间戳系列。随着您进一步往下走,时间戳会以不同的秒数增加。我需要挑出大于 1.5 秒的间隙(可以这么说)并删除它们。

这是列数据的示例:

任务看起来很简单,但我收到“类型不匹配”错误。我对 For Each 循环比较陌生,所以我不太明白哪些部分不匹配。

【问题讨论】:

  • 您的W.Value 是数字格式吗?
  • @mrbungle 你好!谢谢你这么快回复。我不相信它被格式化为数字。我怎样才能有效地做到这一点?
  • @liamwilt - 编辑您的问题以显示 B 列中的数据是什么样的。
  • 我的建议只是在黑暗中快速拍摄。我可以运行这段代码,无论文本或数字格式如何,它都能正常工作。但是,是的,@JasonFaulkner 说的,让我们看看数据

标签: vba excel for-loop range


【解决方案1】:

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

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

  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

【讨论】:

  • 您好,感谢您对此进行调查。所以,类型不匹配已经消失(耶!),但我们现在有一个“需要对象”错误。调试亮点将我指向您回复中写的“If”语句的开头。
  • @liamwilt - 你可以去掉方法中的前缀Sheet。我已经更新了答案。
  • 工作就像一个魅力,先生!感谢您的帮助!
【解决方案2】:

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

使用CDbl 显式转换为Double 可能无法修复类型不匹配 错误,因为如果任何一个值不是数字,事情就会顺利进行- 是否隐式转换。

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    • 1970-01-01
    • 2021-12-24
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多