【问题标题】:How can I Hide Excel rows if SUM of contents = zero and skip rows containing any text?如果内容总和 = 零并跳过包含任何文本的行,如何隐藏 Excel 行?
【发布时间】:2011-12-29 15:36:08
【问题描述】:

根据我提出的上一个问题,我试图隐藏包含零的行,但跳过包含任何一个或多个单元格中的任何文本的行。我以前跳过空白行得到了很好的帮助,现在希望得到更多帮助。我在互联网上搜索了我能找到的每个论坛,但没有找到任何我需要的东西。该隐藏有两个代码和该代码的精确副本,但隐藏设置为 false。这是隐藏的那个。

Sub HideRows()
Dim R As Long
Dim Rng As Range
    If Selection.Rows.Count > 1 Then
        Set Rng = Selection
    Else
        Set Rng = ActiveSheet.UsedRange
    End If      
    For R = 1 To Rng.Rows.Count
    Set myRange = Range(Rng(R, 2), Rng(R, Rng.Columns.Count))
      If Application.CountBlank(myRange) <> myRange.Cells.Count And IsNumeric(myRange(Row)) = False Then
        If Application.Sum(myRange) = 0 Then
        Rng.Rows(R).Hidden = True
        End If
      End If
    Next R        
End Sub

顺便说一句,我知道IsNumeric(myRange(Row)) = False 确实应该是= True,但由于某种原因,在我的一个工作表上,此设置有效,如果我更改为 True,它几乎没有任何作用。

在此先感谢您的帮助。

【问题讨论】:

  • 你不要说这段代码有什么问题。它是否隐藏了不应该隐藏的行?它不隐藏它应该隐藏的行吗?为什么Set myRange ... 从第 2 列开始?
  • 尽可能避免范围循环,它们会严重浪费代码运行时间。而是使用一个简单的工作列(手动或使用 VBA),然后使用 AutoFilter 它。但根据托尼的评论,您的确切问题可能会更清楚
  • 对不起,是的,它隐藏了带有文本的行,这些行是工作表上相应部分的标题。我注意到由于循环需要时间,但是这些应用的区域不是很大,并且与工作表中公式的处理时间相比,这没什么。谢谢你的提示。

标签: text excel skip vba


【解决方案1】:

当我尝试您的代码时,出现以下语法错误:

  • myRange 未定义。
  • 行(如在 myRange(Row) 中)未定义。

您的代码的其他问题:

  • myRange 是一个范围,因此 IsNumeric(myRange) 将始终为 false。
  • If Application.CountBlank(myRange) &lt;&gt; myRange.Cells.Count 表示不隐藏空白行。

IsNumeric 和 IsNumber 都对单个值进行操作。我在文档中找不到任何建议可以使它们对数组、集合或范围进行操作。我的实验产生了与此一致的结果。除了检查一行中的单个单元格之外,我认为没有任何方法可以处理困难的情况。

我想我已经针对所有边界条件测试了以下代码,但我不能保证这一点。它隐藏空白行和只包含零的行。如果选择了一个范围,则该范围之外的列将被视为空白。

Sub HideRows()

  Dim ColCrnt As Integer
  Dim Hide As Boolean
  Dim myRange As Range
  Dim R As Long
  Dim Rng As Range

  If Selection.Rows.Count > 1 Then
    Set Rng = Selection
  Else
    Set Rng = ActiveSheet.UsedRange
  End If
  For R = 1 To Rng.Rows.Count
    Set myRange = Range(Rng(R, 1), Rng(R, Rng.Columns.Count))
    If Application.CountBlank(myRange) = myRange.Cells.Count Then
      ' Blank row
      Hide = True
    ElseIf Application.Sum(myRange) <> 0 Then
      ' At least on numeric cell with a non-zero value
      Hide = False
    Else
      ' Row contains one or more cells containing text, booleans or zeroes
      ' Hide if all these cells are zeros.
      ColCrnt = Rng.Columns.Count
      Set myRange = Rng(R, ColCrnt)
      If IsCellZero(myRange) Or IsEmpty(myRange) Then
        ' Last cell of row is zero or blank so will have to check row
        Do While True
          ' Skip to first non-blank cell to left or column 1
          ' if no non-blank cells
          Set myRange = myRange.End(xlToLeft)
          If myRange.Column < Rng(R, 1).Column Then
            ' Have move outside selection
            Hide = True
            Exit Do
          End If
          If myRange.Column = Rng(R, 1).Column Then
            ' Have reached column 1
            If IsCellZero(myRange) Or IsEmpty(myRange) Then
              ' Column 1 is zero or blank so nothing interesting on row
              Hide = True
              Exit Do
            Else
              ' Column 1 is not zero or blank
              Hide = False
              Exit Do
            End If
          End If
          If Not IsCellZero(myRange) Then
            Hide = False
            Exit Do
          End If
          If myRange.Column = Rng(R, 1).Column Then
            ' No non-zero cells found
            Hide = True
            Exit Do
          End If
        Loop
      Else
        ' Last cell of row is neither zero nor empty
        Hide = False
      End If
    End If
    If Hide Then
      Rng.Rows(R).Hidden = True
    Else
      Rng.Rows(R).Hidden = False
    End If
  Next R
End Sub
Function IsCellZero(Rng As Range) As Boolean

  ' Rng must be a single cell.  Returns true only if Rng.Value is numeric zero

  ' Function uses IsNumber because IsNumeric returns True
  ' for empty cells and booleans

  If Application.WorksheetFunction.IsNumber(Rng.Value) Then
    If Val(Rng.Value) = 0 Then
      IsCellZero = True
    Else
      IsCellZero = False
    End If
  Else
    ' Value is blank, text or boolean
    IsCellZero = False
  End If

End Function

【讨论】:

  • 感谢您的帮助和提示。我试过了,不幸的是它并不能完全满足我的需要。我应该更具体地想要隐藏带有零的行,但跳过空白行和带有文本的行。未引用列 A 的原因是因为它包含与后续列中的数字相对应的名称(交叉表格式)。再次感谢你。这对我理解 VBA 有很大帮助,因为我对它很陌生。
  • 我假设您可以处理必要的小改动。要忽略第 1 列,请在 Set myRange ... 中将起始列更改回 2。接受空白行。删除If Application.CountBlank ...、接下来的两行和ElseIfElse
【解决方案2】:

你的问题的原因是And IsNumeric(myRange(Row)) = False

  1. 行未定义且从未设置。所以它将具有0 的默认值。因此(因为 myRange 是从第 2 列开始定义的)myRange(Row) 指的是 A 行中的单个单元格,myRange 指的是行。
  2. 如果删除 (Row) 位,IsNumeric 将始终返回 FALSE

另外,Set myRange = Range(Rng(R, 2), 指的是使用范围的 R 行,向右偏移一列

结论:

  1. 假设您要测试所有单元格,请更改为 `Set myRange = Range(Rng(R, 1), Rng(R, Rng.Columns.Count))
  2. 要正确测试非数字单元格,请使用
    If Application.Count(myRange) &gt; 0 And _
    Application.CountBlank(myRange) + _ Application.Count(myRange) = myRange.Cells.Count Then

顺便说一句,这是一个很好的做法DIM你所有的变量。这将确定(Row) 的问题。如果您将Option Explicit 添加到模块的顶部,这将成为强制性的。

【讨论】:

  • 这正是我所需要的。感谢您的帮助和建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-13
  • 2012-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-24
相关资源
最近更新 更多