简体   繁体   English

Cells.SpecialCells(xlCellTypeVisible)。循环慢速复制

[英]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.AutoFilterModeoSheet.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.

相关问题 .SpecialCells(xlCellTypeVisible).Copy的更快替代方法 - A faster alternative to .SpecialCells(xlCellTypeVisible).Copy SpecialCells(xlCellTypeVisible)还包括隐藏/过滤的单元格 - SpecialCells(xlCellTypeVisible) also includes hidden/filtered cells SpecialCells(xlCellTypeVisible) - SpecialCells(xlCellTypeVisible) VBA通过.SpecialCells(xlCellTypeVisible)合并自动过滤的单元格 - VBA merging autofiltered cells via .SpecialCells(xlCellTypeVisible).Range 尽管使用了`SpecialCells(xlCellTypeVisible)`,但选择可见单元格不起作用 - Selecting Visible Cells is not working although using `SpecialCells(xlCellTypeVisible)` CurrentRegion.SpecialCells(xlCellTypeVisible) 太慢 - 提高性能的技巧? - CurrentRegion.SpecialCells(xlCellTypeVisible) too slow - Tips to Improve performance? 在下一个工作表循环中,SpecialCells(xlCellTypeVisible) 范围应读取为 NOTHING - SpecialCells(xlCellTypeVisible) range should be read as NOTHING in the next worksheet loop SpecialCells(xlCellTypeVisible)在UDF中不起作用 - SpecialCells(xlCellTypeVisible) not working in UDF SpecialCells(xlCellTypeVisible)选择整个工作表 - SpecialCells(xlCellTypeVisible) choose the whole worksheet 使用Selection.SpecialCells(xlCellTypeVisible)时未选中的单元会受到影响 - Non selected cells being affected when using Selection.SpecialCells(xlCellTypeVisible)'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM