【问题标题】:What is the difference between .Value = "" and .ClearContents?.Value = "" 和 .ClearContents 有什么区别?
【发布时间】:2016-11-22 03:56:13
【问题描述】:

如果我运行以下代码

Sub Test_1()
   Cells(1, 1).ClearContents
   Cells(2, 1).Value = ""
End Sub

当我使用公式 ISBLANK() 检查 Cells(1, 1) 和 Cells(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="" 只是在单元格中放置一个长度为零的字符串,因此您只是在向它写入一个新值(它在技术上不是空白...)@ 987654330@ 实际上是删除单元格的.Value,我想这在内存管理方面有更多的开销。
  • @MacroMan 使用数学类比,您是否暗示.Value="" 等于0 而.ClearContents 等于一个空集?无论如何,感谢 RGA 编辑我的问题。
  • 我个人会使用Value = ""Value = vbNullString 方法而不是ClearContents,因为后者可能会因合并​​单元格而失败。
  • .clearcontents 最糟糕的地方是它破坏了 .copy ,而 =VbNullString 没有

标签: vba excel syntax difference


【解决方案1】:

使用clearcontent 对带有公式的单元格有不同的行为。 当你只有一个值时,行为是相同的,但当你有公式时,行为会有所不同。

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
【解决方案2】:

我确实发现了一个可能值得注意的区别。 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 属性。

最终,就设置值的结果而言,两种方法在功能上是相同的。

【讨论】:

    【解决方案3】:

    当同时在单个单元格中应用时,我认为没有任何合理的延迟,但是当您在范围内应用它时,Range("A1:Z1000").ClearContents 比在嵌套循环或 for 循环中使用 cell(i,j).value="" 更容易和更快

    【讨论】:

      【解决方案4】:

      我遇到这个话题有点晚了,但我想用我的一点代码分享我注意到的东西,我认为我不能完全解释它,但我会尽力而为。

      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 对我来说是最快的。显然,如果您从工作表移动到工作表 EVENTHOUGH 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)

      如果有人能够解释为什么会这样或到底发生了什么,我将不胜感激。

      【讨论】:

        【解决方案5】:

        您会发现 Excel 电子表格有很大的不同。

        假设 B1 由方程填充返回空白 A1 = 5 B1 = "=if(A1=5,"","x")

        在这种情况下,您必须使用 C1 编写的方程式 (1) C1 = (2) C1 =

        解决方案 1 将返回 false,因为单元格中填充了方程式 解决方案 2 将返回 True

        【讨论】:

          【解决方案6】:

          根据我的发现,如果您的目标是简单地拥有一个空单元格并且您不想更改任何有关格式的内容,您应该使用 Value = vbNullString,因为这是最有效的。

          “ClearContents”正在检查和更改单元格中的其他属性,例如格式和公式(从技术上讲,它是一个独立于值的属性)。使用 Value = "" 时,您只需更改一个属性,因此速度更快。使用 vbNullString 会提示编译器您使用的是空字符串,而使用双引号的另一种方式是,它需要一个通用字符串。因为 vbNullString 提示它期待一个空字符串,所以它能够跳过一些步骤并且您可以获得性能提升。

          【讨论】:

          • 更改单元格的.Value如何避免更改单元格的.Formula?这没有多大意义。此外,删除单元格值的方法都不会影响格式。
          • 如果您正在输入带有宏的公式,您应该设置 Range.Formula 属性或 Range.FormulaR1C1 属性。您可以使用.Value 属性设置公式,Excel 会自动意识到它是一个公式并为您移动它(我不确定,但我想旧版本的 ExcelVBA 不会自动为您移动它)。所以使用 Range.ClearContents 是检查 .Formula 参数和 .Value。如果您的 .Value 不以“=”开头,那么它不会对 .Formula 做任何事情,除非清除或忽略它。
          • 所以你的意思是在设置.Value时,Excel必须检查.Formula是否需要更改,但是当你.ClearContents时不需要检查它以某种方式更快,因为它正在做更多的工作?这更没有意义。
          • 我认为.ClearContents 不会更改格式是正确的,因此感谢您的更正。我在原始帖子中所说的是.ClearContents 确实检查了.Formula。所以澄清一下,.ClearContents 肯定会检查和更改.Value.Formula.FormulaR1C1。更改 .Value 可能会检查并更改其他人,如果它检测到“=”,但由于它并不总是检测到,它会做更少的事情,这就是它更快的原因。
          猜你喜欢
          • 2017-02-16
          • 1970-01-01
          • 2016-02-27
          • 2012-04-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多