Excel VBAでシートの最終行や最終列を取得する方法を紹介します。
データ件数に応じて処理範囲を動的に変えたいときに、最終行・最終列の取得はよく使います。
本記事では、End(xlUp)とEnd(xlToLeft)を使った基本コードに加えて、空白時の注意点や実務で使いやすい書き方までまとめました。
この記事でわかること
- VBAで最終行を取得する方法
- VBAで最終列を取得する方法
- 列や行が空のときに1が返る理由
- 空の場合に0を返す書き方
UsedRangeやSpecialCells(xlCellTypeLastCell)との違い
もくじ
VBAで最終行・最終列を取得する基本
最終行・最終列を取得するときによく使われるのが、次の2つです。
- 最終行:
Cells(Rows.Count, 列番号).End(xlUp).Row - 最終列:
Cells(行番号, Columns.Count).End(xlToLeft).Column
これは、Excelで Ctrl + ↑ や Ctrl + ← を押したときに近い動きをする方法です。
特定の列や行を基準にして、最後に値が入っているセルを調べたいときに使います。
【実装コード】最終行を取得する方法
以下のコードは、「Sheet1」シートのA列を基準に、最後にデータが入力されている行番号を取得してlastRowに格納する例です。
必要に応じて、シート名や列を変更してください。
Copyをクリックするとコピーできます。
Sub sample()Dim ws As WorksheetDim lastRow As LongSet ws = Sheets("Sheet1")lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).RowEnd Sub
ws.Cells(ws.Rows.Count, "A")の"A"はA列を表しています。
B列を基準にしたい場合は、ws.Cells(ws.Rows.Count, "B")のように変更します。
Cells(Rows.Count, "A").End(xlUp).Rowの意味
このコードは、次のような流れで最終行を取得しています。
- シートのA列の一番下のセルに移動する
End(xlUp)で上方向にたどる- 最初に見つかったデータ入りセルの行番号を取得する
そのため、A列に連続してデータがある表では特に使いやすい方法です。
最終行の取得で注意したいこと
A列に何も入力されていない場合、ws.Cells(ws.Rows.Count, "A").End(xlUp).Rowは0ではなく1を返します。
これは、上方向にたどった結果として1行目に到達するためです。
つまり、「データがない」ことと「1行目が最終行」であることが区別しにくい点に注意が必要です。
A列が空なら0を返すコード
列全体が空の場合は0を返したい、というケースも多いです。
その場合は、1行目のセルが空かどうかもあわせて確認します。
Copyをクリックするとコピーできます。
Sub sample()Dim ws As WorksheetDim lastRow As LongSet ws = Sheets("Sheet1")lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).RowIf lastRow = 1 And IsEmpty(ws.Cells(1, "A")) ThenlastRow = 0End IfEnd Sub
【実装コード】最終列を取得する方法
以下のコードは、「Sheet1」シートの1行目を基準に、最後にデータが入力されている列番号を取得してlastColumnに格納する例です。
見出し行の最終列を取得したいときによく使います。
Copyをクリックするとコピーできます。
Sub sample()Dim ws As WorksheetDim lastColumn As LongSet ws = Sheets("Sheet1")lastColumn = ws.Cells(1, ws.Columns.Count).End(xlToLeft).ColumnEnd Sub
ws.Cells(1, ws.Columns.Count)の1は1行目を表しています。
2行目を基準にしたい場合は、ws.Cells(2, ws.Columns.Count)のように変更してください。
Cells(1, Columns.Count).End(xlToLeft).Columnの意味
このコードは、次の流れで最終列を取得しています。
- 1行目の一番右のセルに移動する
End(xlToLeft)で左方向にたどる- 最初に見つかったデータ入りセルの列番号を取得する
最終列の取得で注意したいこと
1行目に何も入力されていない場合、ws.Cells(1, ws.Columns.Count).End(xlToLeft).Columnは0ではなく1を返します。
これは、左にたどっていった結果として1列目に到達するためです。
1行目が空なら0を返すコード
行全体が空のときは0を返したい場合、A1が空かどうかもあわせて確認します。
Copyをクリックするとコピーできます。
Sub sample()Dim ws As WorksheetDim lastColumn As LongSet ws = Sheets("Sheet1")lastColumn = ws.Cells(1, ws.Columns.Count).End(xlToLeft).ColumnIf lastColumn = 1 And IsEmpty(ws.Cells(1, "A")) ThenlastColumn = 0End IfEnd Sub
最終行・最終列をまとめて取得するコード
実務では、最終行と最終列をセットで使うことが多いです。
以下のようにまとめて取得しておくと使いやすくなります。
Copyをクリックするとコピーできます。
Sub sample()Dim ws As WorksheetDim lastRow As LongDim lastColumn As LongSet ws = Sheets("Sheet1")lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).RowlastColumn = ws.Cells(1, ws.Columns.Count).End(xlToLeft).ColumnMsgBox "最終行:" & lastRow & vbCrLf & "最終列:" & lastColumnEnd Sub
実務でよくある使い方
最終行までループする
データ件数に応じて行を繰り返し処理したい場合は、最終行を取得してFor文に使います。
Copyをクリックするとコピーできます。
Sub sample()Dim ws As WorksheetDim lastRow As LongDim i As LongSet ws = Sheets("Sheet1")lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).RowFor i = 1 To lastRowDebug.Print ws.Cells(i, "A").ValueNext iEnd Sub
表の範囲を取得する
最終行と最終列がわかれば、データ範囲をまとめて指定できます。
Copyをクリックするとコピーできます。
Sub sample()Dim ws As WorksheetDim lastRow As LongDim lastColumn As LongDim dataRange As RangeSet ws = Sheets("Sheet1")lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).RowlastColumn = ws.Cells(1, ws.Columns.Count).End(xlToLeft).ColumnSet dataRange = ws.Range(ws.Cells(1, 1), ws.Cells(lastRow, lastColumn))dataRange.SelectEnd Sub
End・UsedRange・xlLastCellの違い
最終行・最終列を取得する方法はいくつかあります。
どれを使うかは、何を「最後」とみなしたいかで変わります。
| 方法 | 特徴 | 向いている場面 | 注意点 |
|---|---|---|---|
| End(xlUp) End(xlToLeft) | 特定の列・行を基準に、最後に値が入っているセルを取得しやすい | 一覧表の最終行、見出し行の最終列を取得したいとき | 基準にした列や行が空だと、正しく判定しにくいことがある |
| UsedRange | シート上で使用されている範囲全体を取得できる | ワークシート全体の使用範囲をまとめて把握したいとき | 書式だけ残っているセルも範囲に含まれることがある |
| SpecialCells(xlCellTypeLastCell) | Excelが認識している最後のセルを取得できる | シート全体の右下端を確認したいとき | 過去に使ったセルや書式の影響で、見た目の最終セルとずれることがある |
ただし、UsedRangeやxlCellTypeLastCellは、書式だけ残っているセルや過去に使ったセルの影響を受けることがあります。
そのため、表データの最終行・最終列だけを取りたいなら、まずはEnd(xlUp)とEnd(xlToLeft)を使うのが基本です。
結局どの方法を使えばよい?
「A列を基準に最終行を取得したい」「1行目を基準に最終列を取得したい」といった通常の表データであれば、End(xlUp) と End(xlToLeft) を使う方法がもっとも実用的です。
一方で、シート全体の使用範囲をまとめて確認したい場合は UsedRange、Excel上で認識されている最後のセルを調べたい場合は SpecialCells(xlCellTypeLastCell) が候補になります。
迷ったときは、まず 「どの列・どの行を基準にしたいのか」 を決めると選びやすくなります。
UsedRangeで使用範囲を確認する例
シート全体で現在使われている範囲を確認したい場合は、UsedRangeを使います。
UsedRangeは便利ですが、書式だけ残っているセルも範囲に含まれることがあります。
Copyをクリックするとコピーできます。
Sub sample()Dim ws As WorksheetSet ws = Sheets("Sheet1")Debug.Print ws.UsedRange.AddressEnd Sub
SpecialCells(xlCellTypeLastCell)で最後のセルを確認する例
Excelが認識している最後のセルを確認したい場合は、SpecialCells(xlCellTypeLastCell)を使います。
SpecialCells(xlCellTypeLastCell)は、見た目の最終セルと一致しないことがあります。
Copyをクリックするとコピーできます。
Sub sample()Dim ws As WorksheetDim lastCell As RangeSet ws = Sheets("Sheet1")Set lastCell = ws.Cells.SpecialCells(xlCellTypeLastCell)Debug.Print lastCell.AddressEnd Sub
最終行・最終列を取得するときの注意点
途中に空白があると基準列・基準行によって結果が変わる
たとえばA列を基準に最終行を取得している場合、A列の下のほうが空だと、他の列にデータが残っていても正しく拾えないことがあります。
そのため、必ずデータが入る列を基準にするのがポイントです。
見出し行を基準に最終列を取るなら、見出しが途切れないことが前提
1行目を基準に最終列を取得する場合、見出しセルが途中で空いていると期待どおりの列番号にならないことがあります。
見出しが整っている表で使うと安定しやすいです。
フィルターや非表示行の影響に注意する
表の状態によっては、期待した位置とずれるケースもあります。
特に複雑なシートでは、サンプルデータで一度確認してから使うと安心です。
よくある質問
最終行が1になるのはなぜですか?
基準にした列が空でも、End(xlUp)は上方向にたどって1行目に到達するためです。
そのため、列全体が空のときでも1が返ることがあります。
最終列が1になるのはなぜですか?
End(xlToLeft)が左方向にたどって1列目に到達するためです。
行全体が空でも1になることがあります。
空なら0を返したいです
1が返ったときに、基準セルが本当に空かどうかをIsEmptyで確認すると対応できます。
列番号ではなく列記号を取得できますか?
取得した列番号をもとに、列記号へ変換することもできます。
ただし、通常の処理では列番号のまま使うことが多いです。
まとめ
VBAで最終行・最終列を取得するときは、次の書き方が基本です。
- 最終行:
Cells(Rows.Count, "A").End(xlUp).Row - 最終列:
Cells(1, Columns.Count).End(xlToLeft).Column
ただし、基準にした列や行が空の場合は1が返ることがあるため、必要に応じて空判定を追加します。
まずは、必ず値が入る列や見出しがそろっている行を基準にするのがおすすめです。
最終行・最終列を取得できるようになると、ループ処理や範囲指定がかなり書きやすくなります。
