【初心者用サンプル】行(列)を非表示/再表示するマクロを3パターン紹介

アイキャッチ
行を非表示にするコード

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
  1. 22,27行目…非表示行がない場合、エラーになるので別処理しています。
  2. 31行目…非表示の解除Rows.Hidden = Falseで隠れている行を全て再表示してくれます。
  3. コメントアウト部分…他のパターンと処理時間を比較するのに使用したコードです。コメントアウトを外してコードを実行すると、イミディエイトウィンドウに処理時間が表示されます。不要なら削除してください。
STEP
変数最終行に最下行を代入
STEP
Select Caseステートメントで1が入力されているかチェック、Unionメソッドで結合
STEP
For~NextステートメントSelect Caseステートメントを1行目から最終行まで繰り返す
STEP
Unionメソッドで結合された行を非表示にする

非表示の処理(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行全てを非表示にしてもForNextとの差が(私の環境で)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秒以上かかっています)。

コードもシンプルで分かりやすいし、依頼者にはこのパターンで提出しました。依頼者はすごく喜んでくれましたが、アウトラインでいいんじゃね?という思いが拭い切れない今日この頃です。

よかったらシェアしてね!
  • URLをコピーしました!
目次