【问题标题】:Speeding Up VBA Code for If Then Statement with Formula使用公式加速 If Then 语句的 VBA 代码
【发布时间】:2018-12-24 02:29:43
【问题描述】:

我目前有两个 VBA 代码,它们对于我的大型数据集运行速度非常慢,并且正在寻找优化和加速它们的方法。

第一个公式在 J 列中查找在 A 列中有值的单元格区域,如果它们在 J 中为空白,则输入包含用户定义函数的公式。

第二个代码是查看 J 列中的任何值是否以 , 结尾,如果是,则删除该逗号。任何帮助将不胜感激!

Sub FillEmpty()
    Dim r As Range, LastRow As Long
    LastRow = Cells(Rows.Count, 1).End(xlUp).row
    For Each r In Range("J2:J" & LastRow)
        If r.Text = "" Then r.FormulaR1C1 = _
           "=IFERROR((IF(LEFT(RC[-9],6)=""master"", get_areas(RC[-7]), """")),"""")"
    Next r
End Sub

Sub NoComma()
    Dim c As Range
    For Each c In Range("J:J")
        With c
            If Right(.Value, 1) = "," Then .Value = Left(.Value, Len(.Value) - 1)
        End With
    Next c
End Sub

【问题讨论】:

  • 似乎你应该能够通过在前一个 if 后面加上逗号检查来组合这些
  • 第二个If语句很简单,但是没有FormulaR1C1就不能写第一个吗?顺便说一句,我在上面。我可以为第二个 If 语句使用计算最后一行吗?
  • @VBasic2008 谢谢!绝对可以使用计算第二个 if 语句的最后一行。第一个公式将分别是 A2 和 C2,而不是 RC 语句。

标签: excel vba if-statement optimization


【解决方案1】:

加速:数组

1。代码

令人难以置信的是,当从数组粘贴到范围时,您不需要 formulaR1C1 来将公式放入范围。但它在我的电脑上运行。总而言之,第二个代码中的相同原理应用于第一个代码:Range into Array、Loop 和 Array into Range。没有比这更快的了。第一个代码的另一个想法是创建一个范围联合,然后一次性粘贴公式。

Sub FillEmpty()

  Const cCol As Variant = "J"      ' Column Letter/Number
  Const cFirst As Long = 2         ' First Row

  Dim vntFE As Variant             ' Range Array
  Dim i As Long                    ' Range Array Rows Counter

  ' Paste range into array.
  vntFE = Cells(cFirst, cCol).Resize(Cells(Rows.Count, cCol) _
      .End(xlUp).Row - cFirst + 1)

  ' Loop through array and perform calculation.
  For i = 1 To UBound(vntFE)
    If vntFE(i, 1) = "" Then vntFE(i, 1) = "=IFERROR((IF(LEFT(RC[-9],6)" _
        & "=""master"", get_areas(RC[-7]), """")),"""")"
  Next

  ' Paste array into range.
  Cells(cFirst, cCol).Resize(Cells(Rows.Count, cCol) _
      .End(xlUp).Row - cFirst + 1) = vntFE

End Sub

Sub FillEmptyEasy()

  Const cCol As Variant = "J"      ' Column Letter/Number
  Const cFirst As Long = 2         ' First Row

  Dim rng As Range                 ' Range
  Dim vntFE As Variant             ' Range Array
  Dim LastRow As Long              ' Last Row
  Dim i As Long                    ' Range Array Rows Counter

  ' Calculate Last Row.
  LastRow = Cells(Rows.Count, cCol).End(xlUp).Row
  ' Calculate Range.
  Set rng = Cells(cFirst, cCol).Resize(LastRow - cFirst + 1)
  ' Paste range into array.
  vntFE = rng

  ' Loop through array and perform calculation.
  For i = 1 To UBound(vntFE)
    If vntFE(i, 1) = "" Then vntFE(i, 1) = "=IFERROR((IF(LEFT(RC[-9],6)" _
        & "=""master"", get_areas(RC[-7]), """")),"""")"
  Next

  ' Paste array into range.
  rng = vntFE

End Sub

2。代码

Sub NoComma()

  Const cCol As Variant = "J"      ' Column Letter/Number
  Const cFirst As Long = 2         ' First Row

  Dim vntNoC As Variant            ' Range Array
  Dim i As Long                    ' Range Array Rows Counter

  ' Paste range into array.
  vntNoC = Cells(cFirst, cCol).Resize(Cells(Rows.Count, cCol) _
      .End(xlUp).Row - cFirst + 1)

  ' Loop through array and perform calculation.
  For i = 1 To UBound(vntNoC)
    If Right(vntNoC(i, 1), 1) = "," Then _
        vntNoC(i, 1) = Left(vntNoC(i, 1), Len(vntNoC(i, 1)) - 1)
  Next

  ' Paste array into range.
  Cells(cFirst, cCol).Resize(Cells(Rows.Count, cCol) _
      .End(xlUp).Row - cFirst + 1) = vntNoC

End Sub


Sub NoCommaEasy()

  Const cCol As Variant = "J"      ' Column Letter/Number
  Const cFirst As Long = 2         ' First Row

  Dim rng As Range                 ' Range
  Dim vntNoC As Variant            ' Range Array
  Dim lastrow As Long              ' Last Row
  Dim i As Long                    ' Range Array Rows Counter

  ' Calculate Last Row.
  lastrow = Cells(Rows.Count, cCol).End(xlUp).Row
  ' Calculate Range.
  Set rng = Cells(cFirst, cCol).Resize(lastrow - cFirst + 1)
  ' Paste range into array.
  vntNoC = rng

  ' Loop through array and perform calculation.
  For i = 1 To UBound(vntNoC)
    If Right(vntNoC(i, 1), 1) = "," Then _
        vntNoC(i, 1) = Left(vntNoC(i, 1), Len(vntNoC(i, 1)) - 1)
  Next

  ' Paste array into range.
  rng = vntNoC

End Sub

【讨论】:

  • 谢谢!我不确定你所说的简化第一个代码是什么意思 - 你能解释一下吗?如果有办法将单元格范围设置为仅在 J 列中为空白且在 A 列中以“Master”开头的单元格,则将第一个代码中的公式简化为 =get_areas(C2),然后放入代码中某处的 IFERROR 子句使这些值变为空白。
  • @VictoriaG:我的意思是摆脱公式R1C1。但是好吧,我想你不能,所以我会这样尝试。至少需要一个小时。
  • @VictoriaG:可能就是这样。不确定“r.Text”中发生了什么。我希望它会奏效,因为我注意到你在这个项目上受苦了好几天。
  • 谢谢!!!我尝试了 Sub FillEmptyEasy 的代码并收到有关未定义对象的错误,但其他代码运行良好。几个月,而不是几天:)
  • @VictoriaG:两个简单版本的最后一行都是错误的。只需删除“设置”。对不起。我已经编辑了答案。
猜你喜欢
  • 2019-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-21
相关资源
最近更新 更多