开发者

how to Speed Up the VBA Macros

开发者 https://www.devze.com 2023-01-11 17:09 出处:网络
I am Generating a New Sheets using macros. For a New Sheet generation , Data is retrieved from more than 4 MS Access DB. Each DB had minimum 200 field. My Macro code includes

I am Generating a New Sheets using macros. For a New Sheet generation , Data is retrieved from more than 4 MS Access DB. Each DB had minimum 200 field. My Macro code includes

  1. Cell locking
  2. Alignment and formatting
  3. One third of the cells in the sheet had a formulas
  4. Cell reference with other Workbooks

My problem is ever开发者_JAVA技巧y sheet generation it takes minimum one hour to complete the hole process. But it seems to me it's taking way too long.

I am already added the Application.ScreenUpdating = True to speed up the code but still it takes same time. How to do speed up the code , If you have any idea please guide me.

     `For Ip = 5 To  150
     resp = Range("B" & Ip).Value
     With ActiveSheet.QueryTables.Add(Connection:= _
    "ODBC;DSN=henkel2;DBQ=C:\Hl-RF\RSF-Temp.mdb;DriverId=25;FIL=MS Access;MaxBufferSize=2048;" _
    , Destination:=Range("IV4"))
    .CommandText = "select Vles from " & Shtname & " where cint(PrductID)='" & resp & "' and cint(DepotID) = '" & cnt1 & "' and Mnth = '" & mnths & "' and Type='" & typs & "'"
    .Name = "tab product"
    .FieldNames = True
    .RowNumbers = False
    .FillAdjacentFormulas = False
    .PreserveFormatting = True
    .RefreshOnFileOpen = False
    .BackgroundQuery = True
    .RefreshStyle = xlInsertDeleteCells
    .SavePassword = False
    .SaveData = True
    .AdjustColumnWidth = True
    .RefreshPeriod = 0
    .PreserveColumnInfo = True
    .SourceConnectionFile = _
    "C:\Hl-RF\tabct.odc"
    .Refresh BackgroundQuery:=False
    End With`


    Is There Is any way to Reduce the loop iteration time

Thanks In advance


Surely you mean

Application.ScreenUpdating = False

Apart from that you could also look to disable the recalculation of the workbook whilst the macro is running and see if that makes a difference. This is of course assuming that the bottle neck is with the spreadsheet part of the process, if its taking ages to get the data from access that might be an area to look at


Get hold of a copy of Professional Excel Development which includes an excellent profiling utility called PerfMon. It will allow you to see which parts of the report are taking all the time so you can analyse and rewrite


You can try the usual vba optimization methods of setting calculation to manual and disabling ScreenUpdating.

Dim calc As XlCalculation
calc = Application.Calculation
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

Application.ScreenUpdating = True
Application.Calculation = calc

Put your code or function call between Application.Calculation = xlCalculationManual and Application.ScreenUpdating = True.

This is from my previous Post

Note: I coundn't find info weather or not you run the code from within Access or Excel. If you create the Excel Workbook from Access you probably have some code like this:

Dim xlApp As Excel.Application
Set xlApp = new Excel.Application

In this case you would have to change Application in the code above to xlApp. For example:

xlApp.Calculation = xlCalculationManual


I'd try to do MORE of the work on the database side. Generate the reports you want on the database side, and then export the results to Excel.

Access is MUCH better at automating reports than Excel is.


There is some disucussion of this topic here.

Edit: Ok, then the next step is to identify which parts of your code are taking the longest. The simplest way to do this is to make a copy of your code and just start measuring various parts like this:

Private Declare Function GetTickCount Lib "kernel32.dll" () As Long
Private mlngStrt As Long
Private mlngEnd As Long

Private Const u As Long = 10000000

Public Sub Example()
    Dim i As Long

    mlngStrt = GetTickCount
    For i = 0 To u
    Next
    mlngEnd = GetTickCount
    Debug.Print "Section1", mlngEnd - mlngStrt

    mlngStrt = GetTickCount
    ExampleSubCall
    mlngEnd = GetTickCount
    Debug.Print "ExampleSubCall", mlngEnd - mlngStrt

    mlngStrt = GetTickCount
    For i = 0 To (u * 1.5)
    Next
    mlngEnd = GetTickCount
    Debug.Print "Section2", mlngEnd - mlngStrt
    Debug.Print "Example Complete"
End Sub

Private Sub ExampleSubCall()
    Dim i As Long
    For i = 0 To (u * 0.75)
    Next
End Sub

This approach is fairly straight-forward. The drawback here is that you need to insert all of the timing statements and then turn around and remove them. Which is why I would work on a copy.

Once you know what parts are taking the longest you know where to focus your attention and what to ask for help with.


Take a look at Chris comments. We believe that your performance bottleneck is likely to be in the way you're querying the database rather than in the VBA code that applies the data into the sheet.

Simple questions about Access performance: - Your tables have indexes? - Are you using any kind of table join? - Are the Access databases local on your computer or being accessed remotely?

Again, I'm only reinforcing what Chris already commented.


Yes, make a table in Access to hold your client IDs. Then create the query here and connect to it with the external data connector. After that refresh it manually or use VBA to refresh the connection whenever you're ready.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号