[英]Cells.SpecialCells(xlCellTypeVisible).Copy slow in loop
I have been asked to create a macro the filters an Excel worksheet on one row, creates a new workbook, and copies the filtered rows along with the header and formulas to the new workbook. 我被要求创建一个宏,该宏在一行中过滤Excel工作表,创建一个新工作簿,并将过滤后的行以及标题和公式复制到新工作簿中。 I have created a macro that first reads the target row and generates an array contains the unique values.
我创建了一个宏,该宏首先读取目标行并生成一个包含唯一值的数组。 It then loops through the unique values.
然后,它遍历唯一值。 Within the loop a new workbook is created.
在循环中,将创建一个新的工作簿。 The source worksheet is filtered using auto filter for the unique value.
使用自动过滤器过滤源工作表的唯一值。 The matching rows along with the headers are copied to the new workbook.
匹配的行以及标题将复制到新工作簿中。 The new workbook is saved.
新工作簿已保存。 The first time the loop executes in less than one second.
第一次循环执行的时间少于一秒。 The second time and subsequent times it hangs up on the line:
它第二次及以后挂断电话:
oSheet.Cells.SpecialCells(xlCellTypeVisible).Copy Destination:=oSplitSheet.Range("A1") oSheet.Cells.SpecialCells(xlCellTypeVisible)。复制目标:= oSplitSheet.Range(“ A1”)
It takes almost a minute for this line to execute. 这条线几乎要花一分钟时间才能执行。 I have tried: application.copyandpaste = false, sheet.empty cell.copy, and a Win32 API call to empty the clopboard all to no effect.
我已经尝试过:application.copyandpaste = false,sheet.empty cell.copy和一个Win32 API调用,以清空clopboard都无效。 The test source worksheet is 91 columns wide, 285 rows long, contains a 2 row header, and the filtered column is column B. I have included a copy of the loop below.
测试源工作表宽91列,长285行,包含2行标题,过滤后的列是B列。我在下面提供了循环的副本。 Any suggestions would be helpful.
任何的意见都将会有帮助。
'Create the split books
For lngFilterRow = 1 To lngFilterRowMax
'update the form
Me.txtCurrent = lngFilterRow
DoEvents
'Get the next filter
strFilter = rayFilter(lngFilterRow)
'Get the split sheet name
strSplitName = Me.txtFolder & "\" & strBaseName & "_" & strFilter & ".xlsx"
'Open the target workbook
Set oBook = Application.Workbooks.Add
Set oSplitSheet = oBook.Worksheets(1)
'Set the cell widths
For lngCol = lngColFirst To lngColMax
oSplitSheet.Range(oSplitSheet.Cells(1, lngCol), oSplitSheet.Cells(1, lngCol)).ColumnWidth = rayCol(lngCol).ColumnWidth
Next
'Filter the sheet
oSheet.AutoFilterMode = False
strCell = "$" & Me.txtSource & "$" & lngHeaderRowMax
lngFilterCol = oSheet.Range(strCell).Column
strCell = "$" & Me.txtColumnFirst & "$" & Me.txtHeaderRowLast & ":$" & Me.txtColumnLast & "$" & Me.txtHeaderRowLast
oSheet.Range(strCell).AutoFilter Field:=lngFilterCol, Criteria1:=strFilter
'Paste the fitlered sheet
oSheet.Cells.SpecialCells(xlCellTypeVisible).Copy Destination:=oSplitSheet.Range("A1")
'Get the Row Count
strCell = "$" & Me.txtSource & "$" & lngRowFirst
lngCol = oSplitSheet.Range(strCell).Column
If IsEmpty(oSplitSheet.Cells(lngRowFirst + 1, lngCol).Value) Then
lngSplitRowMax = lngRowFirst
Else
lngSplitRowMax = oSplitSheet.Range(strCell).End(xlDown).Row
End If
'add the formulas and numberformats
For lngCol = lngColFirst To lngColMax
Set oRange = oSplitSheet.Range(oSplitSheet.Cells(lngRowFirst, lngCol), oSplitSheet.Cells(lngSplitRowMax, lngCol))
oRange.NumberFormat = rayCol(lngCol).NumberFormat
oRange.Interior.Color = rayCol(lngCol).BackColor
If rayCol(lngCol).HasFornula Then
Set SourceRange = oSplitSheet.Range(oSplitSheet.Cells(lngRowFirst, lngCol), oSplitSheet.Cells(lngRowFirst, lngCol))
SourceRange.Formula = rayCol(lngCol).Formula
If lngSplitRowMax > lngRowFirst Then
SourceRange.AutoFill Destination:=oRange
End If
End If
Next
'Save the workbook
oBook.SaveAs Filename:= _
strSplitName, _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
oBook.Close savechanges:=False
'Update the progress bar
txtProgressBarB.Width = (txtProgressBarA.Width / lngFilterRowMax) * lngFilterRow
DoEvents
Set oRange = Nothing
Set SourceRange = Nothing
Set SplitRange = Nothing
Set oSplitSheet = Nothing
Set oBook = Nothing
Next
Excel-2007 onward, number of cells increased drastically. 从Excel-2007开始,单元数急剧增加。 So your code will run much faster in Excel-2003.
因此,您的代码将在Excel-2003中运行得更快。 Reason for slowness is that everywhere in your code you are referring all the cells in the worksheet.
速度慢的原因是在代码中的任何地方都引用了工作表中的所有单元格。
Such as 如
Change oSheet.AutoFilterMode
to oSheet.UsedRange.AutoFilterMode
Change oSheet.Cells.SpecialCells(xlCellTypeVisible)
to oSheet.UsedRange.SpecialCells(xlCellTypeVisible)
更改
oSheet.AutoFilterMode
到oSheet.UsedRange.AutoFilterMode
变化oSheet.Cells.SpecialCells(xlCellTypeVisible)
到oSheet.UsedRange.SpecialCells(xlCellTypeVisible)
Review your code and anywhere if you are referring all the cells just confine it to the exact range that you need. 如果要引用所有单元格,则在任何地方查看代码,只需将其限制在所需的确切范围即可。 Mostly, usedrange will take care of that.
通常,usedrange会解决这个问题。 And this will increase your code speed
这将提高您的代码速度
I have found an answer of sorts. 我找到了各种各样的答案。 It seems that Microsoft has changed the events surrounding the use of the clipboard which account for the slow performance.
微软似乎已更改了剪贴板使用相关的事件,这是导致性能下降的原因。 In other words the code is running as designed.
换句话说,代码正在按设计运行。 Please refer the these two references for details: https://social.msdn.microsoft.com/Forums/office/en-US/858c1c9d-a347-473d-8c81-829e22b6f592/slow-excel-2010-macro-execution?forum=exceldev
请参考这两个参考资料以获取详细信息: https : //social.msdn.microsoft.com/Forums/office/en-US/858c1c9d-a347-473d-8c81-829e22b6f592/slow-excel-2010-macro-execution?forum = exceldev
https://social.msdn.microsoft.com/Forums/office/en-US/c15acbd2-abc8-4135-b8af-4598da70c675/specialcells-function-is-very-slow-in-excel-2010?forum=exceldev https://social.msdn.microsoft.com/Forums/office/en-US/c15acbd2-abc8-4135-b8af-4598da70c675/specialcells-function-is-very-slow-in-excel-2010?forum=exceldev
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.