第13回 直感！スグに使える業務向けVBA汎用プロシージャ(空白行・列の自動検知&削除)

私が編纂・配布させていただいているVBA汎用プロシージャの紹介と簡単な解説になります。
以下のリンクから `.bas` ファイルをダウンロードできます（zipファイル）

https://drive.google.com/file/d/11qEUTsq87UItzoKu2okX5WgEopRercCb/view?usp=drive_link

今回紹介するプロシージャは
| プロシージャ名		| 概要						|
|-------------------------------|-----------------------------------------------|
| AutoDeleteBlankRows / AutoDeleteBlankColumns	| 空白行/列を削除						|

の2つになります！
第12回ではシートのデータ範囲を自動的に検知するものでしたが、データ範囲の中に不要な空白行または列が存在した場合、それも配列の中に格納されてしまいました。作りたいシステムによってそれでもいい場合ももちろんありますが、もし空白行・列が不要である場合この2つのプロシージャを適宜使用していただくことでデータを成型することができます。

内部処理は基本同じな為コードはまとめてご紹介します。

## AutoDeleteBlankRows
~~~
Sub AutoDeleteBlankRows(Optional targetSheet As Worksheet)
'------------------------------------------------------------------------------------------------------------------------------
'　概要　　｜データが格納されたセル範囲を自動検知し空白の行を削除
'------------------------------------------------------------------------------------------------------------------------------
'　引数１　｜targetSheet - 対象のワークシートオブジェクト(規定値:ActiveSheet)(Worksheet型)
'------------------------------------------------------------------------------------------------------------------------------
'　実装　　｜Ver.1.1.0(2025/06/14:新規)
'------------------------------------------------------------------------------------------------------------------------------
    
    Dim vLoop       As Long '行ループカウンタ
    Dim hLoop       As Long '列ループカウンタ
    Dim getVarEnd   As Long '最終行番号の取得
    Dim getHorEnd   As Long '最終列番号の取得
    Dim startVar    As Long '配列格納開始行番号
    Dim startHor    As Long '配列格納終了行番号
    Dim endVar      As Long '配列格納開始列番号
    Dim endHor      As Long '配列格納終了列番号
    Dim varMax      As Long '最大最終行番号記憶
    
    If targetSheet Is Nothing Then Set targetSheet = ActiveSheet
    
    'データテーブルの開始・終了列番号の取得
    For hLoop = targetSheet.Columns.Count To 1 Step -1
        getVarEnd = Cells(targetSheet.Rows.Count, hLoop).End(xlUp).Row
        If getVarEnd = 1 And targetSheet.Cells(1, hLoop) = "" Then getVarEnd = 0
        If getVarEnd > 0 And endHor = 0 Then endHor = hLoop
        If getVarEnd > 0 And endHor <> 0 Then startHor = hLoop
        If getVarEnd > varMax Then varMax = getVarEnd
    Next hLoop
    
    'データテーブルの開始・終了行番号の取得
    For vLoop = varMax To 1 Step -1
        getHorEnd = Cells(vLoop, targetSheet.Columns.Count).End(xlToLeft).Column
        If getHorEnd = 1 And targetSheet.Cells(vLoop, 1) = "" Then getHorEnd = 0
        If getHorEnd > 0 And endVar = 0 Then endVar = vLoop
        If getHorEnd > 0 And endVar <> 0 Then startVar = vLoop
    Next vLoop
    
    'データ範囲内のうち空白行のみを削除
    For vLoop = endVar To 1 Step -1
        If Cells(vLoop, targetSheet.Columns.Count).End(xlToLeft).Column = 1 And targetSheet.Cells(vLoop, 1) = "" Then Rows(vLoop).Delete
    Next vLoop
    
End Sub
~~~

## AutoDeleteBlankColumns
~~~
Sub AutoDeleteBlankColumns(Optional targetSheet As Worksheet)
'------------------------------------------------------------------------------------------------------------------------------
'　概要　　｜データが格納されたセル範囲を自動検知し空白の列を削除
'------------------------------------------------------------------------------------------------------------------------------
'　引数１　｜targetSheet - 対象のワークシートオブジェクト(規定値:ActiveSheet)(Worksheet型)
'------------------------------------------------------------------------------------------------------------------------------
'　実装　　｜Ver.1.1.0(2025/06/14:新規)
'------------------------------------------------------------------------------------------------------------------------------
    
    Dim vLoop       As Long '行ループカウンタ
    Dim hLoop       As Long '列ループカウンタ
    Dim getVarEnd   As Long '最終行番号の取得
    Dim getHorEnd   As Long '最終列番号の取得
    Dim startVar    As Long '配列格納開始行番号
    Dim startHor    As Long '配列格納終了行番号
    Dim endVar      As Long '配列格納開始列番号
    Dim endHor      As Long '配列格納終了列番号
    Dim varMax      As Long '最大最終行番号記憶
    
    If targetSheet Is Nothing Then Set targetSheet = ActiveSheet
    
    'データテーブルの開始・終了列番号の取得
    For hLoop = targetSheet.Columns.Count To 1 Step -1
        getVarEnd = Cells(targetSheet.Rows.Count, hLoop).End(xlUp).Row
        If getVarEnd = 1 And targetSheet.Cells(1, hLoop) = "" Then getVarEnd = 0
        If getVarEnd > 0 And endHor = 0 Then endHor = hLoop
        If getVarEnd > 0 And endHor <> 0 Then startHor = hLoop
        If getVarEnd > varMax Then varMax = getVarEnd
    Next hLoop
    
    'データテーブルの開始・終了行番号の取得
    For vLoop = varMax To 1 Step -1
        getHorEnd = Cells(vLoop, targetSheet.Columns.Count).End(xlToLeft).Column
        If getHorEnd = 1 And targetSheet.Cells(vLoop, 1) = "" Then getHorEnd = 0
        If getHorEnd > 0 And endVar = 0 Then endVar = vLoop
        If getHorEnd > 0 And endVar <> 0 Then startVar = vLoop
    Next vLoop
    
    'データ範囲のうち空白列のみ削除
    For hLoop = endHor To 1 Step -1
        If Cells(targetSheet.Rows.Count, hLoop).End(xlUp).Row = 1 And targetSheet.Cells(1, hLoop) = "" Then Columns(hLoop).Delete
    Next hLoop
    
End Sub
~~~

## 動作解説
第12回のサンプルファイルを元に**AutoDeleteBlankRows**と**AutoDeleteBlankColumns**を使ってみましょう！

![Excel-12-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046902/1e4a309f-4ac6-415e-9ab7-68e6fdd06ec4.png)

A列、E列、1行、6行が空白になっております。これらの行・列を削除していきましょう。記述はとっても簡単でアクティブシートであれば引数も必要ないため

~~~
Call AutoDeleteBlankRows
Call AutoDeleteBlankColumns
~~~

たったこれだけで

![Excel-13-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046902/cab3c2d9-b82d-4ed3-b5ca-6da24fe11a38.png)

空白の行が削除されて表がスッキリしました！
スッキリした表に対して**CellToArray**や**AutoCellToArray**を組み合わせることによってとっても簡単にシートのデータを抽出できてしまいます！

また、複数シートにまたがってデータを抽出してさらに何かしらの処理をしたい場合は
~~~
Sub Main()
    
    Dim s As Long 'ループカウンタ
    Dim a As Variant 'データ格納用配列
    
    For s = 1 To Worksheets.Count
        Call AutoDeleteBlankRows(s)
        Call AutoDeleteBlankColumns(s)
        a = AutoCellToArray(s)
        
        '****************************************************
        '配列のペースト等処理(PasteArray,ArrayToCsvなどを活用)
        '****************************************************
        
    Next s
    
End Sub
~~~

このようなコードで実現できます。1からこれらの処理を書こうとすると結構面倒くさいので、ぜひこれら汎用プロシージャを使って楽をしちゃってください！

## 直感！VBAシリーズ記事一覧
もしよろしければ他の記事もご覧ください！

https://qiita.com/Reko/items/3e482f9a73353e964f00

https://qiita.com/Reko/items/af042ae33cdc01e1dc96

https://qiita.com/Reko/items/9e211c9c496e12283f33

https://qiita.com/Reko/items/c2dab7b0e8207f8049df

https://qiita.com/Reko/items/b5abcdf614cef5d4073a

https://qiita.com/Reko/items/3451339e723a34ac7897

https://qiita.com/Reko/items/40c66556ac51a8006ea6

https://qiita.com/Reko/items/0269b2bece07a675e797

https://qiita.com/Reko/items/e2d0d0bf2dea4feface1

https://qiita.com/Reko/items/b995c3da88d25f6e0104

https://qiita.com/Reko/items/bc97d79599cfd431b2f3

https://qiita.com/Reko/items/1731aaddfc6e50c209df

https://qiita.com/Reko/items/554a47f2aa944e2eec5e