嗨,我正在尝试运行此代码,并且该代码以前在其他项目上也可以使用,所以我不明白为什么它不能在此代码上使用。
我试图查看我是否错过了先前代码中的内容,但我不认为自己
Sub DepolPotential()
DataSheet.Activate
Dim DepolPotential As Range
Dim Count1 As Range
Dim Cells1 As Range
Dim Count2 As Range
Set Cells1 = Range("N2", Range("N2").End(xlDown))
Set Cells2 = Range("N2", Range("N2").End(xlDown))
Set Count2 = Range("N2")
Do
Set Cells1 = Range(Count2, Range("N2").End(xlDown))
Set Count1 = Count2
For Each Count1 In Cells1
If Count2 Is Nothing Then
Exit Do
End If
If Count1.Value < 1 And Count1.Offset(3, 0).Value < 1 Then
Set DepolPotential = Count1.Offset(0, -12)
Count1.Offset(0, 20).Value = DepolPotential.Value
Exit For
End If
Next Count1
Dim InstOn As Range
If Count1 Is Nothing Then
Exit Do
End If
Set Cells2 = Range(Count1, Range("N2").End(xlDown))
For Each Count2 In Cells2
If Count2.Value > 1 And Count1.Offset(3, 0).Value > 1 Then
Set InstOn = Count2.Offset(0, -12)
Count2.Offset(0, 21).Value = InstOn.Value
Count2.Offset(1, 22).Value = InstOn.Offset(1, 0).Value
Set Count2 = Count2.Offset(2, 0)
Exit For
End If
Next Count2
Loop Until Count1 Is Nothing
我在网上遇到错误
Set Cells1 = Range(Count2, Range("N2").End(xlDown))
我不确定为什么以前的代码中出现此错误,但并没有给我一个错误。
答案 0 :(得分:4)
我不知道您的数据是什么样子,但是外循环在第二次迭代时以空DataSheet
中断,并出现您描述的错误。这是一件好事,因为cells1.Address
在空白表上是$N$2:$N$1048576
……但这没关系,因为第一个空单元格满足条件并退出了第一个内部循环。
但这只是一种症状,而不是真正的问题。
第二个循环将迭代与第一个循环完全相同的范围,但是这次没有一个空单元格满足条件,并且该循环继续迭代工作表上的每个痛苦行。
当该循环退出时,count2
循环变量引用为Nothing
-这就是第二次迭代爆炸的原因:[_Global|Worksheet].Range
接受几种不同的方法来指定单元格范围,但是{ {1}}是非法的说法。它会引发错误,并突然停止执行。
发生了什么事? VBA语言规范与此处相关:
Nothing
执行完毕后,<for-each-statement>
的值就是<bound-variable-expression>
中最后一个元素的数据值。
按照规范,<collection>
和count1
都应该在退出循环时具有有效的对象引用。但是,似乎Microsoft对VBA语言规范的实现工作有所不同。这是一个最小的repro示例:
count2
运行该代码一次,将Public Sub Test()
Dim c As Collection
Set c = New Collection
c.Add New Collection 'any object will do
Dim o As Object
For Each o In c
'Exit For
Next
Debug.Print o Is Nothing
End Sub
注释掉,然后取消注释该语句并再次运行它。如果循环运行到完成,则Exit For
循环的For Each
循环的“绑定变量”将为Nothing
。
这意味着,如果第一个内部循环执行完毕,那么您在这里将遇到相同的错误:
Set Cells2 = Range(Count1, Range("N2").End(xlDown))
因为那时Count1
将是Nothing
。在空白表上,Count1
指向$N$2
,因此Cells2
变为$N$2:$N$1048576
。
当第二个内部循环运行完成时,Count2
为Nothing
,并且由于循环条件仅查看Count1
... >
Loop Until Count1 Is Nothing
...当将Count2
作为参数传递给_Global.Range
时,外循环的第二次迭代失败,该错误失败,错误1004:
Set Cells1 = Range(Count2, Range("N2").End(xlDown))
我认为创可贴可以解决verify whether Count2 Is Nothing
before using it,尽管这与更改退出条件以同时检查Count1
和Count2
相同:
Loop Until Count1 Is Nothing Or Count2 Is Nothing
...而且我认为这不是正确的解决方案。实际上,我不确定这是 a 解决方案。
我不能百分百确定,因为我没有花太多时间试图弄清楚Count2
不是Nothing
对外部循环的影响(加上我没有任何数据玩),但我认为这可能恰好在做同一件事:
Dim interestingCells As Range
Set interestingCells = DataSheet.Range("N2:N" & DataSheet.Rows.Count).End(xlUp)
Dim cell As Range
For Each cell In interestingCells
If cell.Value < 1 And cell.Offset(3).Value < 1 Then
cell.Offset(0, 20).Value = cell.Offset(0, -12).Value
ElseIf cell.Value > 1 And cell.Offset(3).Value > 1 Then
cell.Offset(0, 21).Value = cell.Offset(0, -12).Value
cell.Offset(1, 22).Value = cell.Offset(1).Value
End If
Next
老实说,我认为 real 解决方案是退后一步,然后准确地重新评估该循环的含义,废弃旧代码并从头开始重写它。其他任何事情都会增加本来就难以理解的代码的复杂性。除了回收的For Each
循环变量之外, row 偏移量尤其令人困惑:详细说明为什么下一行需要受影响的注释将按顺序排列-注意这样的逻辑可能要求以特定的方式对数据进行排序...这可能是一个错误的假设,例如,一个灾难性的错误等待显示其丑陋的头。另请注意,如果迭代范围恰好覆盖整个列,则cell.Offset(n)
在最后一行时,n
的任何正值cell
都会失败,并且如果{<1>}位于工作表的最后一行 near 附近,则大于它下面剩余的行数。
还请注意,n
逻辑用于获取带有数据的最后一行/单元格:这样,一个空工作表将不会运行一次迭代。
最后,请注意明确限定的.End(xlUp)
调用,以便它解析为Range
而不是DataSheet.Range
-这是我见过的几次错误1004之一_Global.Range
的根本原因不是使用不合格的_Global.Range
调用,隐式地指的是Range
是什么。
答案 1 :(得分:0)
启动您的代码。 在线
Set Cells1 = Range (Count2, Range ('N2'). End (xlDown))
Count2一无所有
作为解决方案,请移动代码
If Count2 Is Nothing Then
Exit do
End if
在行之前
Set Cells1 = Range (Count2, Range ('N2'). End (xlDown))