如何从 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 的实现问题)。考虑以下数据:
- 12
- 13
- 15
- 16
- 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
我在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 的实现问题)。考虑以下数据:
- 12
- 13
- 15
- 16
- 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