首先,我不确定VBA问题是属于这里还是属于SuperUser,如果在错误的地方则道歉。
我正在尝试自学VBA,并经历我在网上找到的各种练习/挑战。我已经制作了一个写出乘法表的宏,它几乎肯定是非常低效的,但是在编写循环等方面是一个很好的起点。
我的代码如下:
Sub TimesTable()
Dim TimesTable As Integer
Dim Plot As Integer
Dim Numbers As Long
Dim RowNumbers As Long
Dim StartTime As Double
Dim SecondsElapsed As Double
'Turn off various things to speed up macro
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
'Start Timer
StartTime = Timer
ActiveSheet.Cells.ClearContents
'Ask for and read input into variable
TimesTable = InputBox("Enter a Integer to display Times Table")
'Write Axis lines
For Plot = 1 To TimesTable
ActiveSheet.Range("A1").Offset(0, Plot).Value = Plot
ActiveSheet.Range("A1").Offset(Plot, 0).Value = Plot
ActiveSheet.Range("A2").Select
Next
'Start loop 1 to kick off line writing
For RowNumbers = 1 To TimesTable
'Start loop 2 to write actual lines
For Numbers = 1 To TimesTable
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = RowNumbers * Numbers
Next
ActiveCell.Offset(1, -TimesTable).Select
Next
'Turn on screen updating etc again
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
SecondsElapsed = Round(Timer - StartTime, 2)
'Display time taken to run macro
MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
End Sub
我设法让它全部工作并且在途中学到了一些东西(主要是如何嵌套循环以及Integer有限制),但我想知道是否有更好的方法来编写每个计算而不是使用单元格偏移?此时它会写入计算,向右移动一个单元格,然后当它到达行尾时,偏移回行的开头,然后向下移动一行。我已经读过,为了提高速度,你想尽可能避免引用特定的细胞但是我会如何努力实现这一目标。
答案 0 :(得分:1)
generate (default-cli) on project standalone-pom: org.apache.maven.archetype.exception.ArchetypeGenerationFailure: Error merging velocity templates: Invocation of method 'forName' in class java.lang.Class threw exception java.lang.ClassNotFoundException: com.jh.interfaces.VideoPlayerInterface at archetype-resources/src/main/java/__library-name__Client.java[line 10, column 39]
效率低下。不要选择偏移单元格,而是尝试引用这样的单元格:Select
,这样你就可以获得或设置指定Cells(row, column).Value
和row
上的单元格的值(你可以使用{{ 1}}而不是column
和许多其他:)根据您的需要)。这应该加快你的宏。通常,在VBA中,我们有Formula
类型,它可以表示工作表中的范围。因此,您不需要选择特定范围(这会减慢执行速度)以便引用它们:)
此外,最好使用Value
代替Range
,因为无论如何,所有整数都会在VBA中转换为long refer to this post。
答案 1 :(得分:1)
正如已经指出的那样,.Select
并非必要且缓慢。你想要的是直接引用细胞。下面我有一个没有.Offset
和.Select
的示例。
Sub TimesTable()
Dim ws As Worksheet
Dim TimesTable As Long, Plot As Long
Dim Numbers As Long, RowNumbers As Long
Dim StartTime As Double, SecondsElapsed As Double
Dim Cell As Range
Set ws = ActiveSheet
'Turn off various things to speed up macro
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
'Start Timer
StartTime = Timer
ws.Cells.ClearContents
'Ask for and read input into variable
TimesTable = 100
'Write Axis lines
With ws
For Plot = 1 To TimesTable
.Cells(Plot + 1, 1).Value = Plot
.Cells(1, Plot + 1).Value = Plot
Next
For Each Cell In .Range(.Cells(2, 2), .Cells(TimesTable + 1, TimesTable + 1))
Cell.Value = .Cells(Cell.Row, 1).Value * .Cells(1, Cell.Column).Value
Next Cell
End With
'Turn on screen updating etc again
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
SecondsElapsed = Round(Timer - StartTime, 2)
'Display time taken to run macro
MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
End Sub
我刚用TimesTable = 1000
尝试了它,它可以节省大约20秒。主要区别在于,我使用了For Each
- 循环而不是2 For
- 循环。 For Each
在Cell
中的每个Range
都应该是多重值。另外,为了缩短您的时间,您可以使用Workbooks, Worksheets, etc.
的变量,之后也更容易修改。