如果我运行以下代码
Sub Test_1()
Cells(1, 1).ClearContents
Cells(2, 1).Value = ""
End Sub
当我使用公式ISBLANK()
检查单元格(1,1)和单元格(2,1)时,两个结果都返回TRUE。所以我想知道:
Cells( , ).Value = ""
和Cells( , ).ClearContents
之间有什么区别?
它们本质上是一样的吗?
如果我然后运行以下代码来测试方法之间的时间差:
Sub Test_2()
Dim i As Long, j As Long
Application.ScreenUpdating = False
For j = 1 To 10
T0 = Timer
Call Number_Generator
For i = 1 To 100000
If Cells(i, 1).Value / 3 = 1 Then
Cells(i, 2).ClearContents
'Cells(i, 2).Value = ""
End If
Next i
Cells(j, 5) = Round(Timer - T0, 2)
Next j
End Sub
Sub Number_Generator()
Dim k As Long
Application.ScreenUpdating = False
For k = 1 To 100000
Cells(k, 2) = WorksheetFunction.RandBetween(10, 15)
Next k
End Sub
我在我的机器上获得以下运行时输出
.ClearContents .Value = ""
4.20 4.44
4.25 3.91
4.18 3.86
4.22 3.88
4.22 3.88
4.23 3.89
4.21 3.88
4.19 3.91
4.21 3.89
4.17 3.89
基于这些结果,我们发现方法.Value = ""
平均比.ClearContents
快。一般来说,这是真的吗?为什么会这样?
根据我的发现,如果你的目标是简单地拥有一个空单元格,并且你不想更改任何关于格式的内容,那么你应该使用Value=vbNullString,因为这是最有效的。
"ClearContents"正在检查和更改单元格中的其他属性,如格式和公式(从技术上讲,这是一个独立于Value的属性)。使用Value="时,您只更改一个属性,因此速度更快。使用vbNullString会提示编译器您使用的是空字符串,而使用双引号的另一种方式则需要一个通用字符串。因为vbNullString会提示它期望一个空字符串,所以它可以跳过一些步骤,从而提高性能。
当在单个单元格中同时应用两者时,我认为没有任何明显的区别,但当您在范围Range("A1:Z1000").ClearContents
中应用它时,它比在嵌套循环中使用cell(i,j).value=""
或一个用于循环更容易、更快
我确实发现了一个可能值得注意的区别。ClearContents返回一个值,在我的有限测试中,它的类型似乎是Boolean
(文档中提到了Variant
类型)。
Option Explicit
Public Sub ClearA1()
Dim a As Range
Dim b As Boolean
Set a = Range("A1")
Debug.Print b 'It's False, the default value
b = a.ClearContents
Debug.Print b 'Set to True, as the action was completed
End Sub
我想部分开销来自于ClearContents
确实返回了一个值,在另一种情况下,您只是设置了一个value
属性。
最终,就设定价值的结果而言,两种方法在功能上看起来是相同的。
使用clearcontent
对包含公式的单元格有不同的行为。当你只有一个值时,行为是相同的,但当你有公式时就不同了。
您可以注意到Excel电子表格中有很大的不同。
假设B1由公式填充,返回空白A1=5B1="=如果(A1=5,","x")
在这种情况下,你必须用C1来写方程(1) C1=<isblank(B1)>(2) C1=
解决方案1将返回false,因为单元格中填充了以下等式解决方案2将返回True
我遇到这个话题有点晚,但我想用我的一些代码分享我注意到的事情,我认为我不能完全解释它,但我会尽我所能。
For Each Cell In ws.Range("D12:D161") 'Order feed colom
Select Case Cell.Value
Case 0
Cell.Interior.Color = Cell.Offset(0, -1).Interior.Color
Case 1
Cell.Interior.Color = 10198015
Case 2
Cell.Interior.Color = 11854022
End Select
Cell.value = ""
Next Cell
这是我用来清除一些字段并为D12:D161范围赋予一些颜色的代码。这里没有什么特别的,如果值是0,那么复制你的邻居,如果是1,那么复制红色,如果是2,那么复制绿色。然后清除细胞
但为了让这个代码运行起来,我花了大约5-6秒的时间,我认为这对于一小段代码来说是相当不错的。另外,我在Private Sub Workbook_SheetActivate(ByVal Sh As Object)
上使用了这一点,这让用户很难等待5-6秒来进行屏幕转换。所以我放了一个循环来检查一行中的空,然后跳过。
值得注意的是,这是脚本的一部分,是的,在这段代码中,我关闭了屏幕更新、计算和事件。
For Each Cell In ws.Range("D12:D161") 'Order feed colom
Select Case Cell.Value
Case 0
Cell.Interior.Color = Cell.Offset(0, -1).Interior.Color
Erow = Erow +1
Case 1
Cell.Interior.Color = 10198015
Erow = 0
Case 2
Cell.Interior.Color = 11854022
Erow = 0
End Select
Cell.value = ""
if Erow = 10 then exit for
Next Cell
现在,我不必做149行,而是做了大约58行,这取决于我在列中的数据。但它仍然需要3-4秒才能完全运行。在调试模式下,我注意到没有任何滞后。如果我已经在工作表上手动运行代码,则延迟为0。几乎是即时的,在测试了更多之后,但当使用带有此代码的Private Sub Workbook_SheetActivate(ByVal Sh As Object)
时,它仍然运行3-4秒。在测试了单独的代码行之后,我发现了.Value = ""
。从代码中删除这一行使其运行0.5秒。。。。所以现在我知道我的问题在哪里了,用多种方法清空我的细胞。我注意到.clearcontents
对我来说是最快的。显然,如果你从一张纸移到另一张纸即使ws.
已被宣布为我的活动纸,它也会花很多时间
For Each Cell In ws.Range("D12:D161") 'Order feed colom
Select Case Cell.Value
Case 0
Cell.Interior.Color = Cell.Offset(0, -1).Interior.Color
Erow = Erow +1
Case 1
Cell.Interior.Color = 10198015
Erow = 0
Case 2
Cell.Interior.Color = 11854022
Erow = 0
End Select
Cell.ClearContents 'DONT USE .Value = "", makes the code run slow
if Erow = 10 then exit for
Next Cell
最后。使用上面的代码.value = ""
耗时4-5秒.value = VbNullstring
耗时3-4秒.ClearContents
只花了0.5秒。但仅在工作表转换期间Private Sub Workbook_SheetActivate(ByVal Sh As Object)
如果有人能解释为什么会这样或到底发生了什么,我将不胜感激。