【发布时间】:2012-10-22 17:06:51
【问题描述】:
我没有太多编写宏的经验,因此遇到以下问题需要这个社区的帮助:
我的宏复制在一个工作表中垂直范围内输入的一系列值,然后将这些值水平(转置)粘贴到另一个工作表中。理论上,它会将第一张工作表中的值粘贴到没有内容的第二张工作表的第一行。由于前五行有内容,因此它将值粘贴到第六行。 我在运行宏时遇到的问题是我觉得它太慢了,因此我希望它运行得更快。
我有相同的宏做同样的事情,但是将值粘贴到另一个工作表的第一行,它运行完美。
因此,我的最佳猜测是第二个宏运行缓慢,因为它必须在第六行开始粘贴,并且前 5 行可能有一些内容需要很长时间才能使宏通过(有很多单元格对其他工作簿的引用)来确定下一行粘贴的位置。这是我最好的猜测,因为我对宏几乎一无所知,所以我不能确定问题出在哪里。
我特此向您提供我的宏的代码,并真诚地希望有人能告诉我是什么让我的宏变慢,并为我提供如何使其运行更快的解决方案。我在想一个解决方案可能是宏不应该考虑前五行数据并立即开始在第 6 行粘贴第一个条目。然后在下一次的第 7 行,等等。这可能是一个解决方案,但我不知道如何以一种可以做到这一点的方式编写代码。
感谢您抽出宝贵时间帮助我找到解决方案,代码如下:
Sub Macro1()
Application.ScreenUpdating = False
Dim historyWks As Worksheet
Dim inputWks As Worksheet
Dim nextRow As Long
Dim oCol As Long
Dim myCopy As Range
Dim myTest As Range
Dim lRsp As Long
Set inputWks = wksPartsDataEntry
Set historyWks = Sheet11
'cells to copy from Input sheet - some contain formulas
Set myCopy = inputWks.Range("OrderEntry2")
With historyWks
nextRow = .Cells(.Rows.Count, "A").End(xlUp).Offset(1, 0).Row
End With
With inputWks
Set myTest = myCopy.Offset(0, 2)
If Application.Count(myTest) > 0 Then
MsgBox "Please fill in all the cells!"
Exit Sub
End If
End With
With historyWks
With .Cells(nextRow, "A")
.Value = Now
.NumberFormat = "mm/dd/yyyy hh:mm:ss"
End With
.Cells(nextRow, "B").Value = Application.UserName
oCol = 3
myCopy.Copy
.Cells(nextRow, 3).PasteSpecial Paste:=xlPasteValues, Transpose:=True
Application.CutCopyMode = False
End With
'clear input cells that contain constants
With inputWks
On Error Resume Next
With myCopy.Cells.SpecialCells(xlCellTypeConstants)
.ClearContents
Application.GoTo .Cells(1) ', Scroll:=True
End With
On Error GoTo 0
End With
Application.ScreenUpdating = True
End Sub
【问题讨论】:
-
那个宏看起来应该够快了。我会删除
Application.GoTo .Cells(1)并添加application.calculation= xlCalculationManual/application.Calculation = xlCalculationAutomatic -
是的,对我来说它运行不到一秒钟。你需要多长时间?
-
我同意这一点。我看不出这段代码有什么明显的地方会导致我从编程的角度对其进行编辑。我认为问题在于 1) 被复制的范围的大小以及 2) 被复制的工作簿也有许多链接到其他工作簿的单元格这一事实。此外,工作簿本身的大小可能会导致性能变慢。当然,按照建议打开/关闭 calcs as @nutsch 并检查工作簿的大小。哦,是的,我可以确认必须找到第 6 行是
NOT这里的一个问题,因为它实际上的编码非常好,可以在一瞬间完成! -
因为您关闭了计算,您需要再次将其设置为自动
-
此外,如果您关闭 Application.ScreenUpdating,某些宏也会运行得更快。但是,不要忘记在完成后将其重新打开,并特别确保即使在您的宏出现错误时也将其重新打开(使用适当的错误处理和恢复),因为如果您关闭 ScreenUpdating 它会留下应用程序和用户情况不佳!与计算一样,关闭它会在最后用正在进行的重新计算(或屏幕重绘)换取一个。 (另请注意,恢复屏幕更新可能会使屏幕短暂闪烁。)(另外,Application.EnableEvents 是另一个值得关注的。)