【问题标题】:Efficiently delete all hidden columns and rows in a worksheet有效删除工作表中所有隐藏的列和行
【发布时间】:2015-09-22 11:08:18
【问题描述】:

要删除我正在使用的工作表中的所有隐藏列和行:

 With activeworkbook.Sheets(1)

           LR = LRow(activeworkbook.Sheets(1)) ' will retrieve last row no in the sheet
           lc = LCol(activeworkbook.Sheets(1)) ' will retrieve last column no in the sheet

            For lp = lc To 1 Step -1    'loop through all columns
                If .Columns(lp).EntireColumn.Hidden = True Then .Columns(lp).EntireColumn.Delete
            Next lp

            For lp = LR To 1 Step -1    'loop through all rows
                If .Rows(lp).EntireRow.Hidden = True Then .Rows(lp).EntireRow.Delete
            Next
end with

但这需要很长时间,因为我有 300 多列和 1000 行。当我尝试估算上述操作所需的总时间时,我发现以下几行花费的时间最多:

For lp = lc To 1 Step -1    'loop through all columns
    If .Columns(lp).EntireColumn.Hidden = True Then _
         .Columns(lp).EntireColumn.Delete
Next lp

但下一个循环要快得多。

您对提高执行速度有什么建议吗?

LRow 和 LCol 函数的代码如下,我确认它返回正确的最后一行和最后一列:

Function LRow(sh As Worksheet)
    On Error Resume Next
    LRow = sh.Cells.Find(What:="*", _
                            After:=sh.Range("A1"), _
                            Lookat:=xlPart, _
                            LookIn:=xlFormulas, _
                            SearchOrder:=xlByRows, _
                            SearchDirection:=xlPrevious, _
                            matchCase:=False).Row
    On Error GoTo 0
End Function


Function LCol(sh As Worksheet)
    On Error Resume Next
    LCol = sh.Cells.Find(What:="*", _
                            After:=sh.Range("A1"), _
                            Lookat:=xlPart, _
                            LookIn:=xlFormulas, _
                            SearchOrder:=xlByColumns, _
                            SearchDirection:=xlPrevious, _
                            matchCase:=False).Column
    On Error GoTo 0
End Function

我正在考虑使用 .specialcells 选择所有可见列,并将其反转以进行删除。

【问题讨论】:

  • 很高兴确认您的 LCol(...) 函数正在返回正确的列。由于这通常是一个简短的代码行,我质疑这样的子函数是否甚至是必要的,更不用说返回正确的列索引号了。使用Applciation.ScreenUpdating = False 加快速度。如果要删除公式,请将计算设置为 xlCalculationManualEnableEvents 通常也会截断几毫秒。
  • 如果切换两个循环会发生什么,即先删除行,然后删除列?
  • 好问题,尝试并确认仍然删除行比删除列快得多
  • 尝试此处 OP 中提到的所有设置:stackoverflow.com/questions/5394239/…

标签: excel vba hidden


【解决方案1】:

你可以先扫描行和列,然后批量删除,看看这个:

Sub cooolboy()

Dim Ws As Worksheet, _
    lp As Long, _
    lR As Long, _
    lC As Integer, _
    RowToDelete As String, _
    ColToDelete As String

Set Ws = ActiveWorkbook.Sheets("Sheet4")
RowToDelete = ""
ColToDelete = ""

With Ws
    lR = .Range("A" & .Rows.Count).End(xlUp).Row         'will retrieve last row no in the sheet
    lC = .Cells(1, .Columns.Count).End(xlToLeft).Column  'will retrieve last column no in the sheet

    For lp = 1 To lC    'loop through all columns
        If .Columns(lp).EntireColumn.Hidden Then _
            ColToDelete = ColToDelete & "," & Col_Letter(lp) & ":" & Col_Letter(lp)
    Next lp

    For lp = 1 To lR   'loop through all rows
        If .Rows(lp).EntireRow.Hidden Then _
            RowToDelete = RowToDelete & "," & lp & ":" & lp
    Next lp
    'Get rid of the first comma
    If ColToDelete <> "" Then ColToDelete = Right(ColToDelete, Len(ColToDelete) - 1)
    If RowToDelete <> "" Then RowToDelete = Right(RowToDelete, Len(RowToDelete) - 1)
    'MsgBox ColToDelete & vbCrLf & RowToDelete
    If ColToDelete <> "" Then .Range(ColToDelete).Delete Shift:=xlToLeft
    If RowToDelete <> "" Then .Range(RowToDelete).Delete Shift:=xlUp
End With

End Sub

Function Col_Letter(lngCol As Long) As String
Dim vArr
vArr = Split(Cells(1, lngCol).Address(True, False), "$")
Col_Letter = vArr(0)
End Function

更进一步,看看这篇文章以找到最后一行和最后一列:Error in finding last used cell in VBA

【讨论】:

  • 谢谢...执行上述代码时,我在 .Range(ColToDelete).Delete Shift:=xlToLeft 处收到应用程序定义或对象定义错误
  • 愚蠢的问题,但你确定你有隐藏的列吗?因为它对我来说工作得很好......我只是没有测试它只有 1 行或列。看看编辑中的更正。
  • 我确实尝试了几列,它可以工作,但不适用于多列...例如,我正在尝试使用 ColToDelete 中的字符串删除列
  • EW:EW,EV:EV,EU:EU,ET:ET,ES:ES,ER:ER,EQ:EQ,EP:EP,EO:EO,EN:EN,EM: EM,EL:EL,EK:EK,EJ:EJ,EI:EI,EH:EH,BY:BY,BX:BX,BW:BW,BV:BV,BU:BU,BT:BT,BS:BS, BR:BR,BQ:BQ,BP:BP,BO:BO,BN:BN,BM:BM,BL:BL,BK:BK,BJ:BJ,BI:BI,BH:BH,BG:BG,BE: BE,BD:BD,BC:BC,BB:BB,BA:BA,AU:AU,AT:AT,AS:AS,AR:AR,AQ:AQ,AP:AP,AO:AO,AN:AN, AM:AM,AL:AL,AK:AK,AJ:AJ,AI:AI,AH:AH,AG:AG,AF:AF,AE:AE,AD:AD,AC:AC,AB:AB,AA: AA,Z:Z,Y:Y,X:X,W:W,V:V,U:U,T:T,S:S,R:R,Q:Q,P:P,O:O, N:N,M:M,L:L,K:K,J:J,I:I,H:H,G:G,F:F,E:E,D:D,C:C,B: B
  • 好吧...也许,如果您定义一个计数器并检查在什么限制之后它不再起作用并退出循环以删除这些并重新启动循环(您需要定义另一个变量以在先前扫描的最后一列/行上重新启动循环)。让我知道结果如何!
【解决方案2】:

我设法使用下面的特殊单元使其工作。这比以前的方法快得多,并且在 Excel 2010 及更高版本中运行良好。

Set urng = Activeworkbook.Sheets(1).UsedRange.SpecialCells(xlCellTypeVisible)
                If Not urng Is Nothing Then
                    s = Split(urng.Cells(1, 1).Address, "$")
                    LR = LRow(Activeworkbook.Sheets(1))
                    lc = LCol(Activeworkbook.Sheets(1))
                    icol = urng.Cells(1, 1).Column

' delete hidden colums
                    Set urng2 = Activeworkbook.Sheets(1).Range(Cells(s(2), 1), Cells(s(2), lc))
                    Set oVisible = urng2.SpecialCells(xlCellTypeVisible)
                    Set oHidden = urng2

                    oHidden.EntireColumn.Hidden = False
                    oVisible.EntireColumn.Hidden = True

                    Set oHidden = urng2.SpecialCells(xlCellTypeVisible)
                    oHidden.EntireColumn.Delete
                    oVisible.EntireColumn.Hidden = False

' delete hidden rows
                    Set urng = Activeworkbook.Sheets(1).UsedRange.SpecialCells(xlCellTypeVisible)
                    If Not urng Is Nothing Then
                        's = Split(urng.Cells(1, 1).Address, "$")
                        icol = urng.Cells(1, 1).Column

                        Set urng2 = Activeworkbook.Sheets(1).Range(Cells(1, icol), Cells(LR, icol))
                        'urng2.Select
                        Set oVisible = urng2.SpecialCells(xlCellTypeVisible)
                        Set oHidden = urng2

                        oHidden.EntireRow.Hidden = False
                        oVisible.EntireRow.Hidden = True

                        Set oHidden = urng2.SpecialCells(xlCellTypeVisible)
                        oHidden.EntireRow.Delete
                        oVisible.EntireRow.Hidden = False

                    End If
                End If

【讨论】:

    猜你喜欢
    • 2014-09-24
    • 2020-10-02
    • 2019-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-30
    相关资源
    最近更新 更多