如何使此 VBA 代码更有效?

时间:2021-06-16 21:17:02

标签: excel vba

我正在尝试使用 VBA 宏来自动化一些事情,但我的代码似乎效率很低。我是 VBA 编码的新手,但我有一种强烈的预感,有一种方法可以使此代码运行得更快。有人请看一下,如果有什么方法可以更有效地重写它,请告诉我吗?

Range("D2").Select
ActiveCell.FormulaR1C1 = "=LEFT(RC[-1],2)"
Range(ActiveCell, ActiveCell.Offset(0, 0).End(xlDown)).FillDown

Range("E2").Select
ActiveCell.FormulaR1C1 = "=MID(RC[-2],7,2)"
Range(ActiveCell, ActiveCell.Offset(0, 0).End(xlDown)).FillDown

Range("Z2").Select
ActiveCell.FormulaR1C1 = "=IF(RC[-22]<>""SO"",RC[-22],RC[-12])"
Range(ActiveCell, ActiveCell.Offset(0, 0).End(xlDown)).FillDown

Range("AA2").Select
ActiveCell.FormulaR1C1 = _
    "=IF(OR((RC[-22]=""17""),(RC[-22]<>""11""),(RC[-23]=""SO"")),""HQ"",""Remote"")"
Range(ActiveCell, ActiveCell.Offset(0, 0).End(xlDown)).FillDown

我正在尝试将四列中的函数填充到 A 列中的数据停止的位置,但是当它到达第四个 FillDown 时,需要很长时间。

2 个答案:

答案 0 :(得分:2)

我在这里看到几个问题

  1. 您说...到 A 列中的数据停止的位置,但在 D、E、Z、AA 列上使用了 .End(xlDown)。这可能是将公式填充到工作表的底部。
  2. 您不需要Fill Down,只需将公式应用于指定范围
  3. Select 不是必需的

考虑一下

Sub Demo()
    Dim ws As Worksheet
    Dim LastRow As Long
    
    Set ws = ActiveSheet ' or specify the required sheet
    
    With ws
        ' find where data in column A stops
        LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
        
        If LastRow = 1 Then
            ' there is no data in column A
            Exit Sub
        End If
        
        .Range(.Cells(2, 4), .Cells(LastRow, 4)).FormulaR1C1 = "=LEFT(RC[-1],2)"
        .Range(.Cells(2, 5), .Cells(LastRow, 5)).FormulaR1C1 = "=MID(RC[-2],7,2)"
        .Range(.Cells(2, 26), .Cells(LastRow, 26)).FormulaR1C1 = "=IF(RC[-22]<>""SO"",RC[-22],RC[-12])"
        .Range(.Cells(2, 27), .Cells(LastRow, 27)).FormulaR1C1 = "=IF(OR((RC[-22]=""17""),(RC[-22]<>""11""),(RC[-23]=""SO"")),""HQ"",""Remote"")"
    End With
    
End Sub

答案 1 :(得分:0)

正如@BigBen 所指出的,您可以通过从一开始就引用完整范围来避免使用 .FillDown。您还可以同时避免使用 .Select,方法是使用 .Resize 之类的函数根据当前范围引用更大的范围。

此外,由于您的宏正在将公式写入单元格,您可以通过禁用编辑单元格时发生的自动计算来加速代码。禁用可能从 Worksheet_Change 过程运行的任何事件也是一个好主意。

您可以使用 Application.Calculation = xlCalculationManualApplication.EnableEvents = False 禁用这两个功能。在代码之后,您需要使用 Application.Calculation = xlCalculationAutomaticApplication.EnableEvents = True

将这两个设置恢复为默认值

以下是如何实施这些建议的示例:

    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    
    With Range("D2")
        .Resize(.End(xlDown).Row - .Row).FormulaR1C1 = "=LEFT(RC[-1],2)"
    End With
    
    With Range("E2")
    .Resize(.End(xlDown).Row - .Row).FormulaR1C1 = "=MID(RC[-2],7,2)"
    End With
    
    With Range("Z2")
    .Resize(.End(xlDown).Row - .Row).FormulaR1C1 = "=IF(RC[-22]<>""SO"",RC[-22],RC[-12])"
    End With
    
    With Range("AA2")
    .Resize(.End(xlDown).Row - .Row).FormulaR1C1 = _
        "=IF(OR((RC[-22]=""17""),(RC[-22]<>""11""),(RC[-23]=""SO"")),""HQ"",""Remote"")"
    End With
    
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True

我保留了 .End(xlDown) 方法,因为我不知道您的工作表是什么样的,这可能是匹配您的数据格式的最佳方法。