【问题标题】:does file size effect the speed of vba execution?文件大小会影响 vba 的执行速度吗?
【发布时间】:2017-06-26 01:52:10
【问题描述】:

我有一个包含数百个宏的复杂 Excel 工作簿。一切运行良好。它的大小为 9mb。当我添加额外的工作表(它们是复杂的图表)时,文件大小会跳到 14mb。这不会是一个问题,但有些代码运行非常非常缓慢。特别是,这是一个将大约 60 个单元格从一张纸复制到另一张纸的复制序列。它通常在 5 秒左右发生,但是当文件大小变为 14mb 时,代码需要大约 60 秒......无法忍受。删除工作表可以解决问题。复制序列与我删除的工作表没有任何关系。我错过了什么?

【问题讨论】:

  • 考虑切换设置:application.screenupdating=falseapplication.calculation=xlManualapplication.enableevents=true。只需确保在 VBA 结束时将它们设置回 false 即可。这些将阻止屏幕更新,阻止应用程序更新公式,并将阻止任何工作表或工作簿 vba 事件在您的代码执行时触发。
  • 谢谢。但并不是所有的设置都像你描述的那样,共同点似乎是文件大小

标签: excel vba


【解决方案1】:

宏运行缓慢 (#slowmacros)

« Turn off calculation and screen refresh while macro is running.  Be sure to restore settings when the macro ends.  Some supposedly reset automatically but later releases tend to require you to reset.  Macros may terminate abnormally so don’t use without that thought in mind.  The examples below do not save current settings and restore them but assume normal usage is in effect.

Screen flickering is usually the result of bad coding, but turning off Screen Updating will eliminate the blinking, and speed up a macro.  Turning off calculation can have a more dramatic effect on improving performance.  Use of Special Cells and restriction to used range will greatly improve coding.

Turning off ScreenUpdating and Calculation are the easiest changes to implement.

    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
      '    ooo   Your code here   ooo
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True


    Prior to XL97 (Excel 5 and Excel 97) use
    Application.Calculation = xlManual          'prior to XL97
    Application.Calculation = xlAutomatic     'prior to XL97
                alternative coding: restores previous settings:

      Dim savCalc As Long, savScrnUD As Boolean
      savCalc = Application.Calculation
      savScrnUD = Application.ScreenUpdating
      Application.Calculation = xlCalculationAutomatic
      Application.ScreenUpdating = True
      '    ooo   Your code here   ooo
    done:
      Application.Calculation = savCalc
      Application.ScreenUpdating = savScrnUD

I always want calculation on and there are too many bad macros that fail and macro of my own that fail during testing so I use the version on the left above.  The code on the right above is more correct but prone to problems of leaving calculation off.

For most VBA actions, you don’t have to select the sheet or cell.  Look for such coding to be reworked/removed, you might even be able to remove the need to suppress screen updating if the appearance of the screen is not changed. (Brian Wilson Example: 2000-12-28)

Are there any Worksheet_Change events.

Related to last row problems, macros can take forever to run if they loop through all possible columns and rows instead of restricting activity to the used area.   Examples where such failures commonly occur:  deleting rows with certain content,  inserting rows or columns, selecting an entire column and macro processes entire column instead of cells in the active area.

In a test of one macro adding DIM statements appeared to increase time 30% contrary to good coding practices.  Nevertheless, by dimensioning variables you simplify code writing and maintenance and avoid some additional problems.  Turning off screenupdating saved about 12%, but turning off calculation saved an additional whopping 75%.

Use SpecialCells to reduce selection to cell types of interest (constants, formulas, comments, visible, etc.).  SpecialCells is automatically limited to the used range, which eliminates processing every single cell in a selected column, if a column is selected.  Examples range from 366 seconds without using SpecialCells, to .040 seconds by reducing selection with SpecialCells as seen on Proper, and other Text changes -- Use of Special Cells also see notations on same page.

Dimensioning variables for use with Options Explicit. (#dimensioning)  If you have simply used Dim xyz as variant you can find out the actual type that you used with  MsgBox typename(xyz)  so you can replace variant by its actual type.  (see vba.htm for more information). 

加速 VBA 代码 (#speedupvba)

The biggest things were in the previous topic turning off calculation and display. Here are some additional tips.

Declare variables with their datatype [see table]:  Byte, Boolean, Long, Long, Currency, Decimal, Single, Double, Date, String, Object, Variant (default), and user-defined types, as well as specific types of objects.  A common pitfall is failing to include attributes for each variable on a DIM statement resulting in a data type of variant.

Use long in preference to integer and use double in preference to single as these are what the system actually has to use, and use String instead of Byte.  Also note that anything referring to rows should be immediately changed to long, since 65,536 exceeds the limit of the integer datatype.

Avoid changing the activecell or the active page, unless that is the desired result.  Example to create a new entry after last entry in Column A, not to be confused with last cell row (Ctrl+End), which can in itself be problematic.   (#samplesub)

 Sub SampleSub()
   Cells(Rows.Count,Range("A1").Column).End(xlUp).Offset(1,0).Value _
     ="** New Entry**"
 End Sub

将文件另存为 .XLSB 有帮助吗?

最后,考虑以下链接。

http://professor-excel.com/15-ways-to-speed-up-excel/

http://dmcritchie.mvps.org/excel/slowresp.htm

http://chandoo.org/wp/2014/01/17/big-trouble-in-little-spreadsheet/

https://msdn.microsoft.com/en-us/library/office/ff726673(v=office.14).aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-07
    • 1970-01-01
    • 1970-01-01
    • 2020-12-24
    • 1970-01-01
    • 2011-11-14
    • 2021-10-07
    • 1970-01-01
    相关资源
    最近更新 更多