加速Excel宏VBA代码

时间:2018-03-08 15:16:51

标签: excel vba excel-vba

你有什么建议加快我的vba代码吗?

我使用UserForm让用户检查他想要分析的月份。

一旦用户确认他的选择,此代码将比较数据并在单元格中写入结果(如果找到了某些内容)。

现在,我需要38.7秒才能获得100分。

提前感谢您和最好的问候。

Private Sub Cmd1_Click()
Dim i As Long
Dim j As Long
Dim ult As Long
Dim myFrame As Control
Dim myCheck As Control
Dim StartTime As Double
Dim SecondsElapsed As Double
Application.EnableEvents = False
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
ult = Worksheets("VendutoPassato").Range("B" & Rows.Count).End(xlUp).Row
 StartTime = Timer
For i = 2 To 433
    If Cells(i, 4) <> "" Then
        For Each myFrame In Me.Controls
            If TypeName(myFrame) = "Frame" Then
                For Each myCheck In myFrame.Controls
                    If TypeName(myCheck) = "CheckBox" Then
                        If myCheck.Value = True Then
                            For j = 2 To ult
                                If Cells(i, 4) Like Worksheets("VendutoPassato").Cells(j, 1) And Worksheets("VendutoPassato").Cells(j, 3) Like Month(DateValue("02-" & myCheck.Caption & "-1992")) And Worksheets("VendutoPassato").Cells(j, 2) Like myFrame.Caption Then
                                    Cells(i, 14) = Cells(i, 14) + Worksheets("VendutoPassato").Cells(j, 4)
                                End If
                            Next
                        End If
                    End If
                Next
            End If
        Next
    Else
        If Cells(i, 3) <> "" Then
            For Each myFrame In Me.Controls
                If TypeName(myFrame) = "Frame" Then
                    For Each myCheck In myFrame.Controls
                        If TypeName(myCheck) = "CheckBox" Then
                            If myCheck.Value = True Then
                                For j = 2 To ult
                                    If Cells(i, 3) Like Worksheets("VendutoPassato").Cells(j, 1) And Worksheets("VendutoPassato").Cells(j, 3) Like Month(DateValue("02-" & myCheck.Caption & "-1992")) And Worksheets("VendutoPassato").Cells(j, 2) Like myFrame.Caption Then
                                        Cells(i, 14) = Cells(i, 14) + Worksheets("VendutoPassato").Cells(j, 4)
                                    End If
                                Next
                            End If
                        End If
                    Next
                End If
            Next
        End If
    End If
Next
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Unload UserForm1
End Sub

3 个答案:

答案 0 :(得分:1)

尝试一下,应该快得多:

Private Sub Cmd1_Click()

    Dim wb As Workbook
    Dim wsData As Worksheet
    Dim wsVenduto As Worksheet
    Dim rVendutoData As Range
    Dim myFrame As Control
    Dim myCheck As Control
    Dim aDataIDs As Variant
    Dim aDataValues As Variant
    Dim LastDataRow As Long
    Dim DataIndex As Long
    Dim vID As Variant
    Dim StartTime As Double
    Dim SecondsElapsed As Double

    StartTime = Timer

    With Application
        .Calculation = xlCalculationManual
        .EnableEvents = False
        .ScreenUpdating = False
    End With

    Set wb = ActiveWorkbook
    Set wsData = wb.ActiveSheet
    Set wsVenduto = wb.Sheets("VendutoPassato")
    Set rVendutoData = wsVenduto.Range("A2", wsVenduto.Cells(wsVenduto.Rows.Count, "A").End(xlUp))
    LastDataRow = wsData.Range("C:D").Find("*", wsData.Range("C1"), xlValues, xlWhole, , xlPrevious).Row
    aDataIDs = wsData.Range("C2:D" & LastDataRow).Value
    aDataValues = wsData.Range("N2").Resize(UBound(aDataIDs, 1) - LBound(aDataIDs, 1) + 1).Value

    For DataIndex = LBound(aDataIDs, 1) To UBound(aDataIDs, 1)
        vID = vbNullString
        Select Case Abs((aDataIDs(DataIndex, 2) = "")) + Abs(2 * (aDataIDs(DataIndex, 1) = ""))
            Case 0, 2:  vID = aDataIDs(DataIndex, 2)
            Case 1:     vID = aDataIDs(DataIndex, 1)
        End Select
        If Len(vID) > 0 Then
            For Each myFrame In Me.Controls
                If TypeOf myFrame Is Frame Then
                    For Each myCheck In myFrame.Controls
                        If TypeName(myCheck) = "CheckBox" Then
                            If myCheck.Value = True Then
                                aDataValues(DataIndex, 1) = aDataValues(DataIndex, 1) + WorksheetFunction.SumIfs(rVendutoData.Offset(, 3), _
                                                                                                                 rVendutoData, vID, _
                                                                                                                 rVendutoData.Offset(, 1), myFrame.Caption, _
                                                                                                                 rVendutoData.Offset(, 2), myCheck.Caption)
                            End If
                        End If
                    Next myCheck
                End If
            Next myFrame
        End If
    Next DataIndex

    wsData.Range("N2").Resize(UBound(aDataValues, 1) - LBound(aDataValues, 1) + 1).Value = aDataValues

    With Application
        .Calculation = xlCalculationAutomatic
        .EnableEvents = True
        .ScreenUpdating = True
    End With

    Unload UserForm1

    SecondsElapsed = Timer - StartTime
    MsgBox "Completed successfully in " & SecondsElapsed & " seconds."

End Sub

答案 1 :(得分:0)

为了回答这样的问题,您应该知道执行的最长时间在哪里。我建议这是在Excel文件中写入的过程:

Cells(i, 14) = Cells(i, 14) + Worksheets("VendutoPassato").Cells(j, 4)
Cells(i, 14) = Cells(i, 14) + Worksheets("VendutoPassato").Cells(j, 4)

因此,最好对这些行进行评论,看看它是否足够快。如果速度是好的,那么尝试制作一些结构,记住应该写什么东西和应该写什么。例如某种对象,它记得Cells(i, 14) + Worksheets("VendutoPassato").Cells(j, 4)应该写在Cells(i, 14)中。

完成后,尝试在任务结束时立即编写所有内容。假设它应该更快。

答案 2 :(得分:0)

根据@tehhowch和@Middle的建议,我设法做了一些重大改进。

现在需要8.75秒才能让我达到100。

如果你们知道如何进一步优化它,那么欢迎你!

Private Sub Cmd1_Click()
Dim i As Long
Dim j As Long
Dim ult As Long
Dim myFrame As Control
Dim myCheck As Control
Dim StartTime As Double
Dim SecondsElapsed As Double
Dim arr As Variant
Dim arrx As Variant

Application.EnableEvents = False
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

ult = Worksheets("VendutoPassato").Range("B" & Rows.Count).End(xlUp).Row
arr = Worksheets("VendutoPassato").Range("A2:D" & ult)
arrx = Worksheets("Foglio1").Range("C2:D433")

For i = 1 To 432
    If arrx(i, 2) <> "" Then
        For Each myFrame In Me.Controls
            If TypeName(myFrame) = "Frame" Then
                For Each myCheck In myFrame.Controls
                    If TypeName(myCheck) = "CheckBox" Then
                        If myCheck.Value = True Then
                            For j = 1 To ult - 1
                                If arrx(i, 2) Like arr(j, 1) And arr(j, 3) Like Month(DateValue("02-" & myCheck.Caption & "-1992")) And arr(j, 2) Like myFrame.Caption Then
                                    Cells(i + 1, 14) = Cells(i + 1, 14) + arr(j, 4)
                                    Exit For
                                End If
                            Next
                        End If
                    End If
                Next
            End If
        Next
    Else
        If arrx(i, 1) <> "" Then
            For Each myFrame In Me.Controls
                If TypeName(myFrame) = "Frame" Then
                    For Each myCheck In myFrame.Controls
                        If TypeName(myCheck) = "CheckBox" Then
                            If myCheck.Value = True Then
                                For j = 1 To ult - 1
                                    If arrx(i, 1) Like arr(j, 1) And arr(j, 3) Like Month(DateValue("02-" & myCheck.Caption & "-1992")) And arr(j, 2) Like myFrame.Caption Then
                                        Cells(i, 14) = Cells(i, 14) + arr(j, 4)
                                        Exit For
                                    End If
                                Next
                            End If
                        End If
                    Next
                End If
            Next
        End If
    End If
Next

Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Unload UserForm1
End Sub