VBA Do-while 函数不检查条件(附错误图片)
VBA Do-while function does not check the condition (with error pictures)
数据集是这样的
我想删除C列中的相同值并取D列中相应值的平均值。但是Do-Until函数似乎没有检查条件?
第一次检查第一个重复号的行号,没问题
第二个检查显示指针移动到第 6 行,其中 C 列中的值为空,Do-while 函数不应该 运行,但消息框仍然弹出并跟随错误警告
i = 2
'Do while Sheets(1).Range("C" & i).Value is not empty
Do While IsEmpty(Sheets(1).Cells(i, "C").Value) = False
If Sheets(1).Cells(i, "C").Value = Sheets(1).Cells(i + 1, "C").Value Then
StartNo = i
MsgBox StartNo
Do While Sheets(1).Cells(i + 1, "C").Value = Sheets(1).Cells(i, "C").Value
i = i + 1
Loop
EndNo = i
Sheets(1).Range("D" & StartNo) = WorksheetFunction.Average(Range("D" & StartNo & ":D" & EndNo))
Sheets(1).Rows(StartNo + 1 & ":" & EndNo).Delete
i = StartNo
End If
i = i + 1
Loop
如果您将 i
声明为 Integer 并且您的代码循环到 32,767 以上的行号(VBA 中 Integer 的最大大小),您可能会“溢出”。
如果仅 C 列中的值 显示 为空,但(例如)是一个空字符串值,则可以执行此操作。您可以通过输入公式 =""
然后在单元格上执行 copy/paste 值来创建这样的值:它看起来是空的,但是 IsEmpty(cellReference)
returns False
,工作表公式 ISBLANK()
.
也是如此
因此 IsEmpty()=False
通过了外部 Do While
测试,并且由于当前“非空”单元格下方的任何空单元格的值都将等于当前单元格(因为空单元格等于一个带有空字符串的单元格)现在你的内部 Do While
只是继续沿着列向下直到你得到溢出因为 i
的值变得太大。
直接使用范围可能更容易理解:
Sub Tester()
Dim c As Range, n As Long, v
Set c = Sheets(1).Cells(2, "C") 'start cell
Do While Len(c.value) > 0 'loop while have data (length check is safer than `IsEmpty()`)
n = 1 'reset replicates counter
v = c.value 'read once...
Do While c.Offset(n).value = v
n = n + 1 'increment replicate count
Loop
If n > 1 Then 'have replicates: populate average and delete unwanted rows
c.Offset(0, 1).value = Application.Average(c.Offset(0, 1).Resize(n))
c.Offset(1).Resize(n - 1).EntireRow.Delete
End If
Set c = c.Offset(1, 0) 'next row
Loop
End Sub
数据集是这样的
我想删除C列中的相同值并取D列中相应值的平均值。但是Do-Until函数似乎没有检查条件?
第一次检查第一个重复号的行号,没问题
i = 2
'Do while Sheets(1).Range("C" & i).Value is not empty
Do While IsEmpty(Sheets(1).Cells(i, "C").Value) = False
If Sheets(1).Cells(i, "C").Value = Sheets(1).Cells(i + 1, "C").Value Then
StartNo = i
MsgBox StartNo
Do While Sheets(1).Cells(i + 1, "C").Value = Sheets(1).Cells(i, "C").Value
i = i + 1
Loop
EndNo = i
Sheets(1).Range("D" & StartNo) = WorksheetFunction.Average(Range("D" & StartNo & ":D" & EndNo))
Sheets(1).Rows(StartNo + 1 & ":" & EndNo).Delete
i = StartNo
End If
i = i + 1
Loop
如果您将 i
声明为 Integer 并且您的代码循环到 32,767 以上的行号(VBA 中 Integer 的最大大小),您可能会“溢出”。
如果仅 C 列中的值 显示 为空,但(例如)是一个空字符串值,则可以执行此操作。您可以通过输入公式 =""
然后在单元格上执行 copy/paste 值来创建这样的值:它看起来是空的,但是 IsEmpty(cellReference)
returns False
,工作表公式 ISBLANK()
.
因此 IsEmpty()=False
通过了外部 Do While
测试,并且由于当前“非空”单元格下方的任何空单元格的值都将等于当前单元格(因为空单元格等于一个带有空字符串的单元格)现在你的内部 Do While
只是继续沿着列向下直到你得到溢出因为 i
的值变得太大。
直接使用范围可能更容易理解:
Sub Tester()
Dim c As Range, n As Long, v
Set c = Sheets(1).Cells(2, "C") 'start cell
Do While Len(c.value) > 0 'loop while have data (length check is safer than `IsEmpty()`)
n = 1 'reset replicates counter
v = c.value 'read once...
Do While c.Offset(n).value = v
n = n + 1 'increment replicate count
Loop
If n > 1 Then 'have replicates: populate average and delete unwanted rows
c.Offset(0, 1).value = Application.Average(c.Offset(0, 1).Resize(n))
c.Offset(1).Resize(n - 1).EntireRow.Delete
End If
Set c = c.Offset(1, 0) 'next row
Loop
End Sub