【PR】を含みます。

プログラミング

【VBA】最終行・最終列を取得する方法

VBA 最終行・最終列を取得する方法

Excel VBAでシートの最終行最終列を取得する方法を紹介します。

データ件数に応じて処理範囲を動的に変えたいときに、最終行・最終列の取得はよく使います。

本記事では、End(xlUp)End(xlToLeft)を使った基本コードに加えて、空白時の注意点実務で使いやすい書き方までまとめました。

この記事でわかること

  • VBAで最終行を取得する方法
  • VBAで最終列を取得する方法
  • 列や行が空のときに1が返る理由
  • 空の場合に0を返す書き方
  • UsedRangeSpecialCells(xlCellTypeLastCell)との違い

VBAで最終行・最終列を取得する基本

最終行・最終列を取得するときによく使われるのが、次の2つです。

  • 最終行:Cells(Rows.Count, 列番号).End(xlUp).Row
  • 最終列:Cells(行番号, Columns.Count).End(xlToLeft).Column

これは、Excelで Ctrl + ↑Ctrl + ← を押したときに近い動きをする方法です。

特定の列や行を基準にして、最後に値が入っているセルを調べたいときに使います。

【実装コード】最終行を取得する方法

以下のコードは、「Sheet1」シートのA列を基準に、最後にデータが入力されている行番号を取得してlastRowに格納する例です。

必要に応じて、シート名や列を変更してください。

Copyをクリックするとコピーできます。

VBA
Copy
  1. Sub sample()
  2.     Dim ws As Worksheet
  3.     Dim lastRow As Long
  4.     Set ws = Sheets("Sheet1")
  5.     lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
  6. End Sub

ws.Cells(ws.Rows.Count, "A")"A"はA列を表しています。

B列を基準にしたい場合は、ws.Cells(ws.Rows.Count, "B")のように変更します。

Cells(Rows.Count, "A").End(xlUp).Rowの意味

このコードは、次のような流れで最終行を取得しています。

  1. シートのA列の一番下のセルに移動する
  2. End(xlUp)で上方向にたどる
  3. 最初に見つかったデータ入りセルの行番号を取得する

そのため、A列に連続してデータがある表では特に使いやすい方法です。

最終行の取得で注意したいこと

A列に何も入力されていない場合、ws.Cells(ws.Rows.Count, "A").End(xlUp).Row0ではなく1を返します。

これは、上方向にたどった結果として1行目に到達するためです。

つまり、「データがない」ことと「1行目が最終行」であることが区別しにくい点に注意が必要です。

A列が空なら0を返すコード

列全体が空の場合は0を返したい、というケースも多いです。

その場合は、1行目のセルが空かどうかもあわせて確認します。

Copyをクリックするとコピーできます。

VBA
Copy
  1. Sub sample()
  2.     Dim ws As Worksheet
  3.     Dim lastRow As Long
  4.     Set ws = Sheets("Sheet1")
  5.     lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
  6.     If lastRow = 1 And IsEmpty(ws.Cells(1, "A")) Then
  7.         lastRow = 0
  8.     End If
  9. End Sub

【実装コード】最終列を取得する方法

以下のコードは、「Sheet1」シートの1行目を基準に、最後にデータが入力されている列番号を取得してlastColumnに格納する例です。

見出し行の最終列を取得したいときによく使います。

Copyをクリックするとコピーできます。

VBA
Copy
  1. Sub sample()
  2.     Dim ws As Worksheet
  3.     Dim lastColumn As Long
  4.     Set ws = Sheets("Sheet1")
  5.     lastColumn = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
  6. End Sub

ws.Cells(1, ws.Columns.Count)1は1行目を表しています。

2行目を基準にしたい場合は、ws.Cells(2, ws.Columns.Count)のように変更してください。

Cells(1, Columns.Count).End(xlToLeft).Columnの意味

このコードは、次の流れで最終列を取得しています。

  1. 1行目の一番右のセルに移動する
  2. End(xlToLeft)で左方向にたどる
  3. 最初に見つかったデータ入りセルの列番号を取得する

最終列の取得で注意したいこと

1行目に何も入力されていない場合、ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column0ではなく1を返します。

これは、左にたどっていった結果として1列目に到達するためです。

1行目が空なら0を返すコード

行全体が空のときは0を返したい場合、A1が空かどうかもあわせて確認します。

Copyをクリックするとコピーできます。

VBA
Copy
  1. Sub sample()
  2.     Dim ws As Worksheet
  3.     Dim lastColumn As Long
  4.     Set ws = Sheets("Sheet1")
  5.     lastColumn = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
  6.     If lastColumn = 1 And IsEmpty(ws.Cells(1, "A")) Then
  7.         lastColumn = 0
  8.     End If
  9. End Sub

最終行・最終列をまとめて取得するコード

実務では、最終行と最終列をセットで使うことが多いです。

以下のようにまとめて取得しておくと使いやすくなります。

Copyをクリックするとコピーできます。

VBA
Copy
  1. Sub sample()
  2.     Dim ws As Worksheet
  3.     Dim lastRow As Long
  4.     Dim lastColumn As Long
  5.     Set ws = Sheets("Sheet1")
  6.     lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
  7.     lastColumn = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
  8.     MsgBox "最終行:" & lastRow & vbCrLf & "最終列:" & lastColumn
  9. End Sub

実務でよくある使い方

最終行までループする

データ件数に応じて行を繰り返し処理したい場合は、最終行を取得してFor文に使います。

Copyをクリックするとコピーできます。

VBA
Copy
  1. Sub sample()
  2.     Dim ws As Worksheet
  3.     Dim lastRow As Long
  4.     Dim i As Long
  5.     Set ws = Sheets("Sheet1")
  6.     lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
  7.     For i = 1 To lastRow
  8.         Debug.Print ws.Cells(i, "A").Value
  9.     Next i
  10. End Sub

表の範囲を取得する

最終行と最終列がわかれば、データ範囲をまとめて指定できます。

Copyをクリックするとコピーできます。

VBA
Copy
  1. Sub sample()
  2.     Dim ws As Worksheet
  3.     Dim lastRow As Long
  4.     Dim lastColumn As Long
  5.     Dim dataRange As Range
  6.     Set ws = Sheets("Sheet1")
  7.     lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
  8.     lastColumn = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
  9.     Set dataRange = ws.Range(ws.Cells(1, 1), ws.Cells(lastRow, lastColumn))
  10.     dataRange.Select
  11. End Sub

End・UsedRange・xlLastCellの違い

最終行・最終列を取得する方法はいくつかあります。

どれを使うかは、何を「最後」とみなしたいかで変わります。

方法特徴向いている場面注意点
End(xlUp)
End(xlToLeft)
特定の列・行を基準に、最後に値が入っているセルを取得しやすい一覧表の最終行、見出し行の最終列を取得したいとき基準にした列や行が空だと、正しく判定しにくいことがある
UsedRangeシート上で使用されている範囲全体を取得できるワークシート全体の使用範囲をまとめて把握したいとき書式だけ残っているセルも範囲に含まれることがある
SpecialCells(xlCellTypeLastCell)Excelが認識している最後のセルを取得できるシート全体の右下端を確認したいとき過去に使ったセルや書式の影響で、見た目の最終セルとずれることがある

ただし、UsedRangexlCellTypeLastCellは、書式だけ残っているセルや過去に使ったセルの影響を受けることがあります。

そのため、表データの最終行・最終列だけを取りたいなら、まずはEnd(xlUp)End(xlToLeft)を使うのが基本です。

結局どの方法を使えばよい?

「A列を基準に最終行を取得したい」「1行目を基準に最終列を取得したい」といった通常の表データであれば、End(xlUp)End(xlToLeft) を使う方法がもっとも実用的です。

一方で、シート全体の使用範囲をまとめて確認したい場合は UsedRange、Excel上で認識されている最後のセルを調べたい場合は SpecialCells(xlCellTypeLastCell) が候補になります。

迷ったときは、まず 「どの列・どの行を基準にしたいのか」 を決めると選びやすくなります。

UsedRangeで使用範囲を確認する例

シート全体で現在使われている範囲を確認したい場合は、UsedRangeを使います。

UsedRangeは便利ですが、書式だけ残っているセルも範囲に含まれることがあります。

Copyをクリックするとコピーできます。

VBA
Copy
  1. Sub sample()
  2.     Dim ws As Worksheet
  3.     Set ws = Sheets("Sheet1")
  4.     Debug.Print ws.UsedRange.Address
  5. End Sub

SpecialCells(xlCellTypeLastCell)で最後のセルを確認する例

Excelが認識している最後のセルを確認したい場合は、SpecialCells(xlCellTypeLastCell)を使います。

SpecialCells(xlCellTypeLastCell)は、見た目の最終セルと一致しないことがあります。

Copyをクリックするとコピーできます。

VBA
Copy
  1. Sub sample()
  2.     Dim ws As Worksheet
  3.     Dim lastCell As Range
  4.     Set ws = Sheets("Sheet1")
  5.     Set lastCell = ws.Cells.SpecialCells(xlCellTypeLastCell)
  6.     Debug.Print lastCell.Address
  7. End 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が返ることがあるため、必要に応じて空判定を追加します。

まずは、必ず値が入る列見出しがそろっている行を基準にするのがおすすめです。

最終行・最終列を取得できるようになると、ループ処理や範囲指定がかなり書きやすくなります。

-プログラミング
-,