简体   繁体   English

试图让我的 VBA 运行得更快一点

[英]Trying to make my VBA run a little bit faster

I am New to VBA, so my codes are usually very slow/suboptimized.我是 VBA 的新手,所以我的代码通常非常慢/未优化。

In one of my programs I have cells in the sheet that has to be filled when the user press a button, the renges change depending on the button but the concept is the same.在我的一个程序中,当用户按下按钮时,工作表中有一些单元格必须填充,这些单元格会根据按钮而变化,但概念是相同的。

So I did this monstrosity:所以我做了这个怪物:

Cells((Range("namedrange").Row + 5), 1).Value = ThisWorkbook.Sheets(5).Cells(4, 7).Value
Cells((Range("namedrange").Row + 5), 3).Value = ThisWorkbook.Sheets(5).Cells(4, 8).Value
Cells((Range("namedrange").Row + 5), 5).Value = ThisWorkbook.Sheets(5).Cells(4, 9).Value
Cells((Range("namedrange").Row + 5), 8).Value = ThisWorkbook.Sheets(5).Cells(4, 10).Value
Cells((Range("namedrange").Row + 5) + 1, 1).Value = ThisWorkbook.Sheets(5).Cells(5, 7).Value
Cells((Range("namedrange").Row + 5) + 1, 3).Value = ThisWorkbook.Sheets(5).Cells(5, 8).Value
Cells((Range("namedrange").Row + 5) + 1, 5).Value = ThisWorkbook.Sheets(5).Cells(5, 9).Value
Cells((Range("namedrange").Row + 5) + 1, 8).Value = ThisWorkbook.Sheets(5).Cells(5, 10).Value

but later changed to:但后来改为:

    With Range("namedrange")
        .Offset(5).Columns(1).Value = ThisWorkbook.Sheets(3).Cells(4, 7).Value
        .Offset(5).Columns(3).Value = ThisWorkbook.Sheets(3).Cells(4, 8).Value
        .Offset(5).Columns(5).Value = ThisWorkbook.Sheets(3).Cells(4, 9).Value
        .Offset(5).Columns(8).Value = ThisWorkbook.Sheets(3).Cells(4, 10).Value
        .Offset(6).Columns(1).Value = ThisWorkbook.Sheets(3).Cells(5, 7).Value
        .Offset(6).Columns(3).Value = ThisWorkbook.Sheets(3).Cells(5, 8).Value
        .Offset(6).Columns(5).Value = ThisWorkbook.Sheets(3).Cells(5, 9).Value
        .Offset(6).Columns(8).Value = ThisWorkbook.Sheets(3).Cells(5, 10).Value
    End With

which is a bit faster, however I feel that it is still suboptimized.这有点快,但我觉得它仍然没有优化。 And I would like to know if there is a way to make it cleaner/more elegant.我想知道是否有办法让它更清洁/更优雅。 Just to be noted that there are discontinuities in the columns, eg it starts in the 1st columns but jumps to the 3rd and then to the 5th and at last to the 8th.请注意,列中存在不连续性,例如,它从第一列开始,但跳到第三列,然后跳到第五列,最后跳到第八列。

The code works but it is slow, I just want a way to make it faster/cleaner.该代码有效但速度很慢,我只是想要一种使其更快/更清洁的方法。

Using Variables使用变量

  • In regards to efficiency, that's about it: you're using the most efficient way to copy values from one cell to another aka copying by assignment .关于效率,仅此而已:您正在使用最有效的方式将值从一个单元格复制到另一个单元格,也就是通过赋值进行复制
  • If you want it to be more flexible, maintainable, and readable(?), here are some ideas.如果您希望它更加灵活、可维护和可读(?),这里有一些想法。
  • Additionally, you can move the remaining magic numbers and text to constants at the beginning of the code or even use the constants as arguments.此外,您可以将剩余的幻数和文本移动到代码开头的常量,甚至可以将常量用作 arguments。
Sub CopyValues()
    
    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    
    ' Specify the worksheet if you know it.
    'Dim dnrg As Range: Set dnrg = wb.Sheets("Sheet1").Range("NamedRange")
    ' Otherwise, make sure the workbook is active.
    If Not wb Is ActiveWorkbook Then wb.Activate
    Dim dnrg As Range: Set dnrg = Range("NamedRange")
    
    Dim drg As Range: Set drg = dnrg.Range("A1,C1,E1,H1").Offset(5)
    Dim cCount As Long: cCount = drg.Cells.Count
    
    ' If you know the tab name, use it instead of the index (3).
    Dim sws As Worksheet: Set sws = wb.Sheets(3)
    Dim srg As Range: Set srg = sws.Range("G4").Resize(, cCount)
    
    Dim r As Long, c As Long
        
    For r = 0 To 1
        For c = 1 To cCount
            drg.Offset(r).Cells(c).Value = srg.Offset(r).Cells(c).Value
        Next c
    Next r

End Sub

You can try to disable screenupdating during execution.您可以尝试在执行期间禁用屏幕更新。

Disable ScreenUpdating禁用屏幕更新

  1. To disable ScreenUpdating, at the beginning of your code put this line:要禁用 ScreenUpdating,请在代码开头放置以下行:
    Application.ScreenUpdating = False

Enable ScreenUpdating启用屏幕更新

  1. To re-enable ScreenUpdating, at the end of your code put this line:要重新启用 ScreenUpdating,请在代码末尾放置以下行:
    Application.ScreenUpdating = True

I wonder what would happen if you use all the.Offset parameters, row and column.我想知道如果你使用所有的.Offset参数,行和列会发生什么。 Example:例子:

With Range("namedrange")
    .Offset(5, 0).Value = ThisWorkbook.Sheets(3).Cells(4, 7).Value
    .Offset(5, 2).Value = ThisWorkbook.Sheets(3).Cells(4, 8).Value
    .Offset(5, 4).Value = ThisWorkbook.Sheets(3).Cells(4, 9).Value
    .Offset(5, 7).Value = ThisWorkbook.Sheets(3).Cells(4, 10).Value
    .Offset(6, 0).Value = ThisWorkbook.Sheets(3).Cells(5, 7).Value
    .Offset(6, 2).Value = ThisWorkbook.Sheets(3).Cells(5, 8).Value
    .Offset(6, 4).Value = ThisWorkbook.Sheets(3).Cells(5, 9).Value
    .Offset(6, 7).Value = ThisWorkbook.Sheets(3).Cells(5, 10).Value
End With

Accessing Excel for values from VBA is a slow operation and this adds up when you make multiple requests.从 VBA 访问 Excel 的值是一个缓慢的操作,当您发出多个请求时,这会加起来。 When you are essentially retrieving the same information on a repetitive basis there are two two methods can be used to reduce access times.当您实际上是在重复检索相同的信息时,可以使用两种方法来减少访问时间。

  1. Replace a lookup with a calculated value用计算值替换查找
  2. Use a with statement使用 with 语句

Thus you code could be written as因此你的代码可以写成

Dim myCol as long 
myCol =Range("namedrange").Row + 5

With ThisWorkook.Sheets(5)
    Cells(myCol, 1).Value = .Cells(4, 7).Value
    Cells(myCol, 3).Value = .Cells(4, 8).Value
    Cells(myCol, 5).Value = .Cells(4, 9).Value
    Cells(myCol, 8).Value = .Cells(4, 10).Value
    myCol=myCol+1 ' trivial example
    Cells(mycol, 1).Value = .Cells(5, 7).Value
    Cells(myCol, 3).Value = .Cells(5, 8).Value
    Cells(myCol, 5).Value = .Cells(5, 9).Value
    Cells(myCol, 8).Value = .Cells(5, 10).Value
End with

Please also install the free, opensource, and fantastic Rubberduck addin for VBA. The code inspections will help you write VBA that is much more correct.还请为 VBA 安装免费、开源和出色的 Rubberduck 插件。代码检查将帮助您编写更正确的 VBA。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM