Excel 如何加快涉及格式化的vba代码的速度?

Excel 如何加快涉及格式化的vba代码的速度?,excel,vba,Excel,Vba,我正在设置一个新的定价计划,根据所选标准从“注册”选项卡读取所选信息,并将其复制到新选项卡中。这些数据是格式化的,所以看起来很美观。 我发现格式化代码大大降低了运行速度。如果可能的话,我想加快速度,因为我将重复多次 我已经把这个计划加快了一个合理的速度。最初需要30秒,而现在大约需要10秒。 我已尽可能地关注本网站的信息: 我觉得仍有改进的余地,尽管我不确定如何改进,我正在寻找更好的方法来改进代码,使其运行更快 Option Explicit Sub create_pricing_schedu

我正在设置一个新的定价计划,根据所选标准从“注册”选项卡读取所选信息,并将其复制到新选项卡中。这些数据是格式化的,所以看起来很美观。 我发现格式化代码大大降低了运行速度。如果可能的话,我想加快速度,因为我将重复多次

我已经把这个计划加快了一个合理的速度。最初需要30秒,而现在大约需要10秒。 我已尽可能地关注本网站的信息:

我觉得仍有改进的余地,尽管我不确定如何改进,我正在寻找更好的方法来改进代码,使其运行更快

Option Explicit
Sub create_pricing_schedule()

'define workbook variables
Dim Start_Time As Double, End_Time As Double
Dim file1 As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Dim ws4 As Worksheet
Dim namedRange1 As Range
Dim namedRange2 As Range
Set file1 = ThisWorkbook
Set ws2 = file1.Worksheets("Pricing Schedule")
Set ws3 = file1.Worksheets("Control")
Set ws4 = file1.Worksheets("Register")
Set namedRange1 = file1.Names("Client_Register").RefersToRange
Set namedRange2 = file1.Names("Pricing_Range").RefersToRange

'define general variables
Dim i As Integer
Dim collect(1 To 500, 1 To 10) As Variant
Dim rw As Range
Dim selectedClient As String
Dim lastrow As Integer, lastrow2 As Integer, lastrow3 As Integer

i = 1

'time how long it takes to improve efficiency
Start_Time = Timer

'speedup so less lagg
Call speedup

'delete everything from the pricing schedule/reset
With Sheets("Pricing Schedule")
    .UsedRange.ClearContents
    .Cells.Interior.ColorIndex = 0
    .Cells.Borders.LineStyle = xlNone
    .Cells.HorizontalAlignment = xlLeft
    .Cells.MergeCells = False
    .Range("A:Z").WrapText = False
    .Rows.RowHeight = "15"
End With

'resize the client register
lastrow = ws4.Range("A100000").End(xlUp).Row
With ActiveWorkbook.Names("Client_Register")
    .RefersTo = "=Register!$A$1:$AE$" & lastrow
End With

selectedClient = ws3.Range("B3").Value
'copy from database to the pricing schedule as a non formatted list of all the info - this runs quickly, but I am open to changing it
For Each rw In Range("Client_Register").Rows
    If Range("Client_Register").Cells(rw.Row, 2) = selectedClient Then
        collect(i, 1) = Range("Client_Register").Range("E" & rw.Row)
        collect(i, 2) = Range("Client_Register").Range("D" & rw.Row)
        collect(i, 3) = Range("Client_Register").Range("F" & rw.Row)
        collect(i, 4) = Range("Client_Register").Range("J" & rw.Row)
        collect(i, 5) = Range("Client_Register").Range("K" & rw.Row)
        collect(i, 6) = Range("Client_Register").Range("L" & rw.Row)
        collect(i, 7) = Range("Client_Register").Range("M" & rw.Row)
        collect(i, 8) = Range("Client_Register").Range("P" & rw.Row)
        collect(i, 9) = Range("Client_Register").Range("I" & rw.Row)
        collect(i, 10) = Range("Client_Register").Range("H" & rw.Row) ' used to determine if pass through fee

        ws2.Range("B" & i + 6) = collect(i, 1)
        ws2.Range("C" & i + 6) = collect(i, 2)
        ws2.Range("D" & i + 6) = collect(i, 3)
        ws2.Range("E" & i + 6) = collect(i, 4)
        ws2.Range("F" & i + 6) = collect(i, 5)
        ws2.Range("G" & i + 6) = collect(i, 6)
        ws2.Range("H" & i + 6) = collect(i, 7)
        ws2.Range("I" & i + 6) = collect(i, 8)
        ws2.Range("J" & i + 6) = collect(i, 9)
        ws2.Range("K" & i + 6) = collect(i, 10)

        i = i + 1
    End If
Next

'add in the colour and count how many rows there are
lastrow2 = ws2.Range("C5000").End(xlUp).Row
With ActiveWorkbook.Names("Pricing_Range")
    .RefersTo = "='Pricing Schedule'!$A$1:$K$" & lastrow2
End With

ws2.Range("B7" & ":" & "J" & lastrow2).Interior.Color = RGB(242, 242, 242)

'==========this bit is slow, can it be quicker?==========
'add spacing, titles, and colour to sub headers
i = 7
For Each rw In Range("Pricing_Range").Rows
    If Range("Pricing_Range").Cells(i, 3) <> Range("Pricing_Range").Cells(i + 1, 3) Then
        Range("Pricing_Range").Rows(i + 1).Insert Shift:=xlShiftDown
        Range("Pricing_Range").Rows(i + 1).Insert Shift:=xlShiftDown
        Range("Pricing_Range").Rows(i + 1).Interior.ColorIndex = 0
        Range("Pricing_Range").Rows(i + 2).Interior.ColorIndex = 0

        Range("Pricing_Range").Range("B" & i + 2 & ":" & "J" & i + 2).Interior.Color = RGB(255, 128, 1)
        Range("Pricing_Range").Range("B" & i + 2 & ":" & "J" & i + 2).Borders(xlEdgeTop).Color = RGB(0, 0, 0)
        Range("Pricing_Range").Range("B" & i + 2 & ":" & "J" & i + 2).Borders(xlEdgeBottom).Color = RGB(0, 0, 0)
        Range("Pricing_Range").Range("B" & i + 2).Value = Range("Pricing_Range").Range("C" & i + 3).Value

        'if it is a pass through fee then add it in to the sub headers
        If Range("Pricing_Range").Range("K" & i + 3).Value = "Pass-Through" Then
            Range("Pricing_Range").Range("J" & i + 2).Value = "Pass-Through Fees"
            Range("Pricing_Range").Range("J" & i + 2).HorizontalAlignment = xlRight
        End If
        i = i + 3

        Else
        i = i + 1
    End If
Next
'==================================================

'set up the main title rows
ws2.Select
Range("Pricing_Range").Range("B2").Value = ws3.Range("B3").Value
Range("Pricing_Range").Range("B2").Font.Size = 20
Range("Pricing_Range").Range("B2").Font.Bold = True
Range("Pricing_Range").Range("B2").Font.FontStyle = "Calibri Light"
Range("Pricing_Range").Range("B2:J3").Select
With Selection
    .HorizontalAlignment = xlCenter
    .VerticalAlignment = xlCenter
    .WrapText = False
    .MergeCells = True
    .Cells.Interior.Color = RGB(255, 128, 1)
    .Cells.Borders(xlEdgeTop).Color = RGB(0, 0, 0)
    .Cells.Borders(xlEdgeBottom).Color = RGB(0, 0, 0)
End With

'tidy up things in the sheet
With Worksheets("Pricing Schedule")
'set up the headers and first title
    .Range("B6") = .Range("C7")
    .Range("B5:J6").Interior.Color = RGB(255, 128, 1)
    .Range("B5:J5").Borders(xlEdgeTop).Color = RGB(0, 0, 0)
    .Range("B5:J5").Borders(xlEdgeBottom).Color = RGB(0, 0, 0)
    .Range("B6:J6").Borders(xlEdgeTop).Color = RGB(0, 0, 0)
    .Range("B6:J6").Borders(xlEdgeBottom).Color = RGB(0, 0, 0)
    .Range("B5").Value = "Fee Code"
    .Range("C5").Value = "Product Line"
    .Range("D5").Value = "Item"
    .Range("E5").Value = "Volume From"
    .Range("F5").Value = "Volume To"
    .Range("G5").Value = "Frequency"
    .Range("H5").Value = "Location"
    .Range("I5").Value = "Price"
    .Range("J5").Value = "Nature of Fee"

'tidy up column widths
    .Range("A5").RowHeight = 30
    .Range("A1").ColumnWidth = 2
    .Range("B1").ColumnWidth = 15
    .Range("C1").ColumnWidth = 40
    .Range("D1").ColumnWidth = 45
    .Range("E1").ColumnWidth = 11
    .Range("F1").ColumnWidth = 11
    .Range("G1").ColumnWidth = 35
    .Range("H1").ColumnWidth = 15
    .Range("I1").ColumnWidth = 12
    .Range("J1").ColumnWidth = 50
    .Range("J:J").WrapText = True
    .Range("K:K").Delete
End With

'clear the extra orange line at the end
lastrow3 = ws2.Range("B1000").End(xlUp).Row
With ws2.Rows(lastrow3 + 2)
    .Cells.Interior.ColorIndex = 0
    .Cells.Borders.LineStyle = xlNone
    .ClearContents
End With

'add print area
With Worksheets("Pricing Schedule")
    .PageSetup.Zoom = False
    .PageSetup.Orientation = xlPortrait
    .PageSetup.PrintArea = "$B$2:$J$" & lastrow3
    .PageSetup.FitToPagesWide = 1
    .PageSetup.FitToPagesTall = False
    .PageSetup.PrintTitleRows = "$2:$6"
End With

'return to normal
Call slowdown

'time how long it takes to improve efficiency
End_Time = Timer
Worksheets("Control").Cells(6, 2) = End_Time - Start_Time
End Sub

Sub speedup()
Application.Calculation = xlManual
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayStatusBar = False

End Sub

Sub slowdown()
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.DisplayStatusBar = True
End Sub
选项显式
子创建定价计划()
'定义工作簿变量
变暗开始时间为双倍,结束时间为双倍
将文件1设置为工作簿
将ws1设置为工作表
将ws2设置为工作表
将ws3设置为工作表
将ws4设置为工作表
Dim NAME DRANGE1作为范围
Dim namedRange2 As范围
Set file1=此工作簿
设置ws2=file1.工作表(“定价计划”)
设置ws3=file1.工作表(“控件”)
设置ws4=file1.工作表(“注册表”)
Set namedRange1=file1.name(“客户机注册”).refrestorange
Set namedRange2=file1.name(“定价范围”).refrestorange
'定义一般变量
作为整数的Dim i
变光收集(1到500,1到10)作为变型
变暗rw As范围
Dim selectedClient作为字符串
将lastrow设置为整数,将lastrow2设置为整数,将lastrow3设置为整数
i=1
“提高效率需要多长时间
开始时间=计时器
“加快速度,减少滞后
呼叫加速
'从定价计划中删除所有内容/重置
附页(“定价表”)
.UsedRange.ClearContents
.Cells.Interior.ColorIndex=0
.Cells.Borders.LineStyle=xlNone
.Cells.HorizontalAlignment=xlLeft
.Cells.MergeCells=False
.Range(“A:Z”).WrapText=False
.Rows.RowHeight=“15”
以
'调整客户端注册表的大小
lastrow=ws4.Range(“A100000”).End(xlUp).Row
使用ActiveWorkbook.Names(“客户机注册”)
.referesto=“=注册!$A$1:$AE$”&lastrow
以
selectedClient=ws3.范围(“B3”).值
'将所有信息以非格式列表的形式从数据库复制到定价计划-这运行得很快,但我愿意更改它
对于范围内的每个rw(“客户_寄存器”)。行
如果范围(“客户机注册”)单元格(rw.Row,2)=选择客户机,则
收集(i,1)=范围(“客户机注册”).范围(“E”和rw.行)
收集(i,2)=范围(“客户机注册”).范围(“D”和rw.行)
收集(i,3)=范围(“客户机注册”).范围(“F”和rw.行)
收集(i,4)=范围(“客户机注册”).范围(“J”和rw.行)
收集(i,5)=范围(“客户机注册”).范围(“K”和rw.行)
收集(i,6)=范围(“客户机注册”).范围(“L”和rw.行)
收集(i,7)=范围(“客户机注册”).范围(“M”和rw.行)
收集(i,8)=范围(“客户登记簿”).范围(“P”和rw.行)
收集(i,9)=范围(“客户机注册”).范围(“i”和rw.行)
收集(i,10)=范围(“客户登记簿”).范围(“H”和rw.行)”,用于确定是否需要通过费用
范围(“B”&i+6)=收集(i,1)
范围(“C”&i+6)=收集(i,2)
ws2.范围(“D”&i+6)=收集(i,3)
ws2.范围(“E”&i+6)=收集(i,4)
ws2.范围(“F”&i+6)=收集(i,5)
范围(“G”&i+6)=收集(i,6)
ws2.范围(“H”&i+6)=收集(i,7)
ws2.Range(“I”&I+6)=收集(I,8)
ws2.范围(“J”&i+6)=收集(i,9)
ws2.范围(“K”&i+6)=收集(i,10)
i=i+1
如果结束
下一个
'添加颜色并计算有多少行
lastrow2=ws2.范围(“C5000”).结束(xlUp).行
使用ActiveWorkbook.Names(“定价范围”)
.referesto=“=‘定价计划’!$A$1:$K$”&最后一行2
以
ws2.Range(“B7”和“:”和“J”和lastrow2.Interior.Color=RGB(242、242、242)
’===============这一点很慢,能快一点吗==========
'为子标题添加间距、标题和颜色
i=7
对于范围内的每个rw(“定价范围”)。行
如果范围(“定价范围”)。单元格(i,3)范围(“定价范围”)。单元格(i+1,3),则
范围(“定价范围”)。行(i+1)。插入移位:=xlShiftDown
范围(“定价范围”)。行(i+1)。插入移位:=xlShiftDown
范围(“定价范围”)。行(i+1)。Interior.ColorIndex=0
范围(“定价范围”)。行(i+2)。Interior.ColorIndex=0
范围(“定价范围”)。范围(“B”和i+2&“:”和“J”和i+2)。Interior.Color=RGB(255,128,1)
范围(“定价范围”)。范围(“B”和i+2&“:”和“J”和i+2)。边框(xlEdgeTop)。颜色=RGB(0,0,0)
范围(“定价范围”)。范围(“B”和i+2&“:”和“J”和i+2)。边框(xlEdgeBottom)。颜色=RGB(0,0,0)
范围(“定价范围”)。范围(“B”和i+2)。值=范围(“定价范围”)。范围(“C”和i+3)。值
'如果是通过费,则将其添加到子标题中
如果范围(“定价范围”).Range(“K”&i+3).Value=“通过”,则
范围(“定价范围”)。范围(“J”和i+2)。Value=“通过费用”
范围(“定价范围”)。范围(“J”和i+2)。水平对齐=xlRight
如果结束
i=i+3
其他的
i=i+1
如果结束
下一个
'==================================================
'设置主标题行
ws2.选择
范围(“定价范围”).范围(“B2”).值=ws3.范围(“B3”).值
范围(“定价范围”)。范围(“B2”)。Font.Size=20
范围(“定价范围”)。范围(“B2”)。Font.Bold=True
范围(“定价范围”).Range(“B2”).Font.FontStyle=“Calibri Light”
范围(“定价范围”)。范围(“B2:J3”)。选择
有选择
.HorizontalAlignment=xlCenter
.垂直对齐=xlCenter
.WrapText=False
.MergeCells=True
.Cells.Interior.Color=RGB(255、128、1)
.Cells.Borders(xlEdgeTop).Color=RGB(0,0,0)
.Cells.Borders(xlEdgeBottom).Color=RGB(0,0,0)
以
“整理床单上的东西
有工作
'copy from database to the pricing schedule as a 
'   non formatted list of all the info - this runs quickly, 
'   but I am open to changing it
With Range("Client_Register")

    For Each rw In .Rows
        If .Cells(rw.Row, 2) = selectedClient Then

            collect(i, 1) = .Range("E" & rw.Row)
            collect(i, 2) = .Range("D" & rw.Row)
            collect(i, 3) = .Range("F" & rw.Row)
            collect(i, 4) = .Range("J" & rw.Row)
            collect(i, 5) = .Range("K" & rw.Row)
            collect(i, 6) = .Range("L" & rw.Row)
            collect(i, 7) = .Range("M" & rw.Row)
            collect(i, 8) = .Range("P" & rw.Row)
            collect(i, 9) = .Range("I" & rw.Row)
            collect(i, 10) = .Range("H" & rw.Row)

            'you could even skip the row-by-row population of values
            '  and assign as a block after exiting the loop
            ws2.Range("B" & i + 6).Resize(1, 10).Value = _
                    Array(collect(i, 1), collect(i, 2), collect(i, 3), _
                          collect(i, 4), collect(i, 5), collect(i, 6), _
                          collect(i, 7), collect(i, 8), collect(i, 9), _
                          collect(i, 10))

            i = i + 1
        End If
    Next

End With
 Range("A1:A10").Range("A1") 'refers to A1
 Range("A2:A10").Range("A1") 'refers to A2
'****EDIT****Changed this to direct range reference rather than go through the Names collection.
'Set namedRange1 = file1.Names("Client_Register").RefersToRange
'Set namedRange2 = file1.Names("Pricing_Range").RefersToRange
Set namedRange1 = file1.Range("Client_Register")
Set namedRange2 = file1.Range("Pricing_Range")

'delete everything from the pricing schedule/reset
'****EDIT***
With ws2 'Sheets("Pricing Schedule")
    'used range takes more time rather use .cells directly
    .Cells.ClearContents
'I am using i for the row count
        ws2.Range("B" & i + 6).Value = namedRange1.Cells(i, 5).Value
        ws2.Range("C" & i + 6).Value = namedRange1.Cells(i, 4).Value
        ws2.Range("D" & i + 6).Value = namedRange1.Cells(i, 6).Value
        ws2.Range("E" & i + 6).Value = namedRange1.Cells(i, 10).Value
        ws2.Range("F" & i + 6).Value = namedRange1.Cells(i, 11).Value
        ws2.Range("G" & i + 6).Value = namedRange1.Cells(i, 12).Value
        ws2.Range("H" & i + 6).Value = namedRange1.Cells(i, 12).Value
        ws2.Range("I" & i + 6).Value = namedRange1.Cells(i, 16).Value
        ws2.Range("J" & i + 6).Value = namedRange1.Cells(i, 9).Value
        ws2.Range("K" & i + 6).Value = namedRange1.Cells(i, 8).Value
        i = i + 1
        Range("Pricing_Range").Rows(i + 1).Insert Shift:=xlShiftDown
        Range("Pricing_Range").Rows(i + 1).Insert Shift:=xlShiftDown