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

ht4b089n  于 2023-01-10  发布在  其他
关注(0)|答案(4)|浏览(188)

我是VBA新手,所以我的代码通常非常慢/次优化。
在我的一个程序中,当用户按下按钮时,工作表中的单元格必须被填充,强度根据按钮而变化,但概念是相同的。
所以我做了这个怪物:

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

但后来改为:

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

这是一个有点快,但我觉得它仍然是次优化。我想知道是否有一种方法,使它更干净/更优雅。只是要注意,有不连续的列,eidogg.它开始在第1列,但跳到第3,然后到第5,最后到第8。
代码工作,但它是缓慢的,我只是想要一种方法,使它更快/更干净。

elcex8rz

elcex8rz1#

使用变量

  • 关于效率,这就是:您正在使用最有效的方法将值从一个单元格复制到另一个单元格,即 * 通过赋值复制 *。
  • 如果您希望它更灵活、更易维护、更易读(?),这里有一些想法。
  • 此外,您可以将剩余的幻数和文本移到代码开头的常量中,甚至可以将常量用作参数。
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
kqlmhetl

kqlmhetl2#

我想知道如果你使用all.Offset参数行和列会发生什么。例如:

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
ykejflvf

ykejflvf3#

从VBA访问Excel以获取值是一个缓慢的操作,当您发出多个请求时,速度会加快。当您重复检索相同的信息时,可以使用两种方法来减少访问时间。
1.用计算值替换查找
1.使用with语句
因此,您的代码可以编写为

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

也请安装免费的,开源的,奇妙的Rubberduck addin for VBA。代码检查将帮助您编写更正确的VBA。

z5btuh9x

z5btuh9x4#

您可以尝试在执行过程中禁用屏幕更新。

禁用屏幕更新

1.要禁用ScreenUpdating,请在代码开头放置以下行:
第一个月

启用屏幕更新

1.要重新启用ScreenUpdating,请在代码末尾添加以下行:
Application.ScreenUpdating = True

相关问题