Range(“A1”).EntireRow.Hidden = TrueまたはRows(1).Hidden = trueで1行目を非表示にします。
Range(“A1”).EntireColumn.Hidden = TrueまたはColumns.(1).Hidden = trueで1列目を非表示にします。
RangeオブジェクトのEntireRowプロパティ(行全体)を使うかRowsプロパティの行番号を使うかの違いで、結果はどちらも同じです。
行の非表示/表示を切り替えるマクロを練習用サンプルとして用意しましたFor Nextステートメントを利用したVBAコードです。条件分岐とループ処理の基本が練習できるサンプルになっています。最後のサンプルは速度にこだわった「高速化仕様」です。
仕様
「エクセルの行を非表示/再表示するのに折りたたみ機能(アウトライン)を使ってるんだけど、作業領域が減るから画面のスクロール量が増えるんだよね。何とかならない?」という依頼に対応したコードです。3パターンほど用意しました。
- A列を判定列とし、1が入力されている行を、マクロ実行ごとに非表示/再表示する
もちろん複数行にも対応します。
For Next ステートメントを使用したコード
Sub 非表示_1()
Dim 非表示行 As Range
Dim 最終行 As Long
Dim i As Long
'Dim stimer As Double
'Dim ftimer As Double
' stimer = Timer
With ActiveSheet.UsedRange
最終行 = .Rows(.Rows.Count).Row
End With
For i = 1 To 最終行
Select Case Cells(i, 1).Value
Case 1
If 非表示行 Is Nothing Then
Set 非表示行 = Cells(i, 1)
Else
Set 非表示行 = Union(非表示行, Cells(i, 1))
End If
End Select
Next i
On Error GoTo エラー表示 '※1
非表示行.EntireRow.Hidden = True
' ftimer = Timer
' Debug.Print ftimer - stimer
Exit Sub
エラー表示: '※1
MsgBox "該当する行がありません", vbExclamation
End Sub
Sub 非表示の解除() '※2
Rows.Hidden = False
End Sub
- 22,27行目…非表示行がない場合、エラーになるので別処理しています。
- 31行目…非表示の解除はRows.Hidden = Falseで隠れている行を全て再表示してくれます。
- コメントアウト部分…他のパターンと処理時間を比較するのに使用したコードです。コメントアウトを外してコードを実行すると、イミディエイトウィンドウに処理時間が表示されます。不要なら削除してください。
非表示の処理(Unionメソッドにより結合されたもの)をFor~Nextステートメントの外で行うので、処理が1回で済みます。
For Each Next ステートメントを使用したコード
Sub 非表示_2()
Dim 非表示行 As Range
Dim 最終行 As Long
Dim r As Range
'Dim stimer As Double
'Dim ftimer As Double
' stimer = Timer
With ActiveSheet.UsedRange
最終行 = .Rows(.Rows.Count).Row
End With
For Each r In Range("A1", Cells(最終行, 1))
Select Case r.Value
Case 1
If 非表示行 Is Nothing Then
Set 非表示行 = r
Else
Set 非表示行 = Union(非表示行, r)
End If
End Select
Next r
On Error GoTo エラー表示
非表示行.EntireRow.Hidden = True
' ftimer = Timer
' Debug.Print ftimer - stimer
Exit Sub
エラー表示:
MsgBox "該当する行がありません", vbExclamation
End Sub
流れはFor~Nextステートメントと同じです。「For Each Nextの方が早い」と書かれているサイトをよく見かけますし、実際その通りですが、処理の量によってはほとんど差が出ません。
このコードの場合、1,048,576行全てを非表示にしてもFor~Nextとの差が(私の環境で)4秒程度でした。大量のデータを処理するのでなければ書きやすい方を使って下さい。
高速化目的でSpecialCellsメソッドを使用したコード
以前、OfficeVBAリファレンスに書いてあったことを思い出して作成したコードです。
Sub 非表示_3()
Dim 非表示行 As Range
Dim 最終行 As Long
'Dim stimer As Double
'Dim ftimer As Double
' stimer = Timer
With ActiveSheet.UsedRange
最終行 = .Rows(.Rows.Count).Row
End With
Set 非表示行 = Range("A1", Cells(最終行, 1))
On Error GoTo エラー表示
非表示行.SpecialCells(xlCellTypeConstants, xlNumbers).EntireRow.Hidden = True
' ftimer = Timer
' Debug.Print ftimer - stimer
Exit Sub
エラー表示:
MsgBox "該当する行がありません", vbExclamation
End Sub
これらの追加VBAパフォーマンスの最適化を使用する
Range.SpecialCellsメソッドを使用して、コードで操作するセルの数を詳しく調べます
https://docs.microsoft.com/ja-jp/office/vba/excel/concepts/excel-performance/excel-tips-for-optimizing-performance-obstructions
Amazonにある中華商品の説明文のような自動翻訳はともかく、SpecialCellsメソッド を使えば処理が早くなるというMicrosoft公式見解。
試してみるとこれがとにかく高速。1,048,576行全て非表示にするのに1秒かかりませんでした(前述の2パターンは10秒以上かかっています)。
コードもシンプルで分かりやすいし、依頼者にはこのパターンで提出しました。依頼者はすごく喜んでくれましたが、アウトラインでいいんじゃね?という思いが拭い切れない今日この頃です。