2011-12-29 2 views
1

В соответствии с предыдущим вопросом я попросил скрыть строки, содержащие нули, но пропустить строки, содержащие любой текст в любой одной или нескольких ячейках. Я получил отличную помощь, ранее пропуская пустые строки, и теперь надеялся на большую помощь. Я искал через Интернет на каждом форуме, который я могу найти, и не нашел ничего, что делает то, что мне нужно. На этом скрывается два кода и точная копия этого, но с скрытым значением false. Вот та, которая скрывается.Как скрыть строки Excel, если SUM содержимого = нуль и пропустить строки, содержащие любой текст?

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, но по какой-то причине на одном из моих рабочих листов эта установка работает и если я изменяю Правда это в значительной степени ничего не делает.

Спасибо заранее, за любую помощь.

+2

Вы не говорите, что не так с этим кодом. Скрывает ли строки, что не должно? Не скрывает ли он строки? Почему «Set myRange ...» начинается с столбца 2? –

+0

Избегайте диапазонов циклов, где вы можете, это ужасные отходы времени выполнения кода. Вместо этого используйте простой рабочий столбец (вручную или с VBA), а затем «AutoFilter». Но в соответствии с комментарием Тони ваша точная проблема может быть более ясной. – brettdj

+1

Прошу прощения, да, это прячет строки с текстом в них, которые являются заголовками для соответствующего раздела на листе. Я заметил, что это требует времени из-за циклов, но области, которые они применяют, не очень большие, и по сравнению с временем обработки формул в листах это ничего. Спасибо за советы. – ThaddeusTG

ответ

2

Причиной Ваших проблем является And IsNumeric(myRange(Row)) = False

  1. Row не определено и никогда не установлено. Таким образом, оно будет иметь значение по умолчанию 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) > 0 And _
    Application.CountBlank(myRange) + _ Application.Count(myRange) = myRange.Cells.Count Then

Кстати, хорошая практика DIM все, что вам переменные. Это определило бы проблему с (Row). Если вы добавите Option Explicit в начало своего модуля, это станет мандатом.

+0

Это действительно то, что мне нужно. Благодарим вас за помощь и советы. – ThaddeusTG

3

Когда я попробовал ваш код, я получил следующие синтаксические ошибки:

  • MyRange не определен.
  • Строка (как в myRange (Row)) не определена.

Другие проблемы с вашим кодом:

  • MyRange является диапазон так IsNumeric (MyRange) всегда будет ложным.
  • If Application.CountBlank(myRange) <> 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 
+0

Благодарим вас за помощь и советы. Я пробовал это, и, к сожалению, он не делает именно то, что мне нужно. Я должен был быть более конкретным о желании просто скрыть строки нулями, но пропустить пустые строки и строки с текстом. Причина, по которой столбец A не ссылается, заключается в том, что он содержит имена, соответствующие номерам в последующих столбцах (формат кросс-таблицы). Еще раз спасибо. Это было большой помощью в моем понимании VBA, так как я очень новичок в этом. – ThaddeusTG

+0

Я предполагаю, что вы можете справиться с незначительными изменениями. Чтобы игнорировать столбец 1, в «Set myRange ...» измените начальный столбец на 2. Чтобы принять пустые строки. delete 'If Application.CountBlank ...', следующие две строки и 'Else'' ElseIf'. –