【VBA】最終行を取得する3つの方法|違いと使い分けを解説

スポンサーリンク

「データの最終行って、どうやって取得すればいいの?」

VBAでマクロを書き始めると、必ずぶつかるのがこの疑問ですよね。行数が毎回変わるデータを処理するには、最終行を自動で取得する方法を知っておく必要があります。

でも安心してください。VBAで最終行を取得する方法はいくつかあり、仕組みを理解すれば迷わず使いこなせるようになります。この記事では代表的な3つの方法をコード付きで解説し、それぞれの違い・使い分け・よくあるトラブルの対処法まで、まとめてお伝えしますね。

VBAで最終行を取得する方法3選

最終行を取得する方法は複数ありますが、ここでは実務でよく使われる3つの方法を紹介します。

End(xlUp)で最終行を取得する(最もよく使う方法)

まずはVBAで最終行を取得する定番コードです。

Dim lastRow As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row

このコードは「A列の最終行」を取得しています。仕組みをかんたんに説明すると、こんな流れです。

  1. Rows.Count でシートの最大行数(1,048,576行)を取得する
  2. Cells(1048576, 1) でA列の一番下のセルを指定する
  3. .End(xlUp) で、そこから上方向にデータが入っているセルを探す
  4. .Row で、見つかったセルの行番号を数値で返す

これはExcelで Ctrl + 上矢印キー を押したときと同じ動きです。シートの一番下から上に向かってデータを探すので、途中に空白セルがあっても正確に最終行を見つけられます。

列を変更したいとき は、Cells(Rows.Count, 1) の数値部分を変えてください。

'--- B列の最終行を取得 ---
lastRow = Cells(Rows.Count, 2).End(xlUp).Row

'--- C列の最終行を取得 ---
lastRow = Cells(Rows.Count, 3).End(xlUp).Row

A列=1、B列=2、C列=3……と、列番号を数値で指定します。セルの指定方法について詳しく知りたい方は「【VBA】RangeとCellsはどう違う?使い分けを実例で解説」を参考にしてみてください。

NOTE

Rows.Count はワークシートの最大行数を自動で返してくれます。Excel 2007以降のファイル形式(.xlsx / .xlsm)では1,048,576行、Excel 2003以前の形式(.xls)では65,536行です。Rows.Count を使えばファイル形式に関係なく正しい最大行数が取得できるので、数値を直接書く必要はありません。

UsedRangeで最終行を取得する

2つ目の方法は UsedRange プロパティを使う方法です。

Dim lastRow As Long
lastRow = ActiveSheet.UsedRange.Rows.Count + ActiveSheet.UsedRange.Row - 1

UsedRange はワークシートで「使用されている範囲」を返すプロパティです。データが入力されている範囲全体を自動で判定してくれます。

ただし注意点が1つあります。UsedRange はデータだけでなく、書式が設定されているだけのセル(背景色や罫線だけ入っているセル)も「使用済み」とみなします。そのため、データの最終行よりも大きな値が返ってくることがあります。

'--- シンプルに書く場合(1行目からデータが始まっている前提) ---
lastRow = ActiveSheet.UsedRange.Rows.Count

1行目からデータが始まっている場合は上のシンプルな書き方でも問題ありません。ただし、1行目が空白の場合は結果がずれるので、最初に紹介した完全版の計算式を使うようにしてください。

SpecialCellsで最終行を取得する

3つ目は SpecialCells メソッドを使う方法です。

Dim lastRow As Long
lastRow = Cells.SpecialCells(xlCellTypeLastCell).Row

SpecialCells(xlCellTypeLastCell) は、ワークシートで最後に使用されたセルを返します。これはExcelで Ctrl + End を押したときと同じ動作です。

この方法も UsedRange と同様に、書式のみのセルも考慮されるため、実際のデータの最終行よりも大きな値が返る場合があります。

'--- 最終列も同時に取得したいとき ---
Dim lastRow As Long
Dim lastCol As Long
lastRow = Cells.SpecialCells(xlCellTypeLastCell).Row
lastCol = Cells.SpecialCells(xlCellTypeLastCell).Column

最終行と最終列を同時に取得できるのが、この方法の便利なポイントです。

3つの方法の違いと使い分け

ここまで紹介した3つの方法を比較表で整理してみましょう。

項目End(xlUp)UsedRangeSpecialCells
取得対象指定した列のデータ最終行シート全体の使用範囲シート全体の使用範囲
空白セルの影響受けにくい受けにくい受けにくい
書式のみのセル無視する含む含む
特定の列を指定できるできないできない
Excel操作での同等機能Ctrl + 上矢印なしCtrl + End
おすすめ度最もおすすめ状況による状況による

結論:迷ったら End(xlUp) を使いましょう。 特定の列に対して正確な最終行を取得でき、書式だけのセルに惑わされないため、実務で最も信頼性が高い方法です。

UsedRange や SpecialCells は「シート全体でどこまでデータがあるか」をざっくり把握したい場面で役立ちます。たとえば、データの範囲を一括でコピーしたいときなどに使うと便利ですよ。

VBA 最終行の取得でよくあるトラブルと対処法

最終行の取得はシンプルに見えますが、いくつかハマりやすいポイントがあります。事前に知っておけば慌てずに済むので、チェックしておきましょう。

空白セルがあると正しく取得できない

End(xlUp) ではなく End(xlDown) を使うと、空白セルがある場合に正しく最終行を取得できません。

'--- End(xlDown) を使った場合 ---
lastRow = Cells(1, 1).End(xlDown).Row

このコードはA1セルから下方向にデータを探します。一見すると自然な発想ですが、ここに落とし穴があります。

途中に空白セルがあると、そこで止まってしまうんです。たとえば A1〜A5 にデータがあり、A6 が空白、A7〜A10 にもデータがある場合、End(xlDown)A5 を最終行として返します。本当の最終行はA10なのに、途中で止まってしまうんですね。

'--- 安全な方法(End(xlUp)を使う) ---
lastRow = Cells(Rows.Count, 1).End(xlUp).Row

下から上に探す End(xlUp) なら、途中の空白セルに影響されません。基本的には End(xlUp) を使うクセ をつけておくのがおすすめです。

取得した値が想定と違うときの確認ポイント

「コードは正しいはずなのに、取得した最終行が想定と違う……」というときは、次の3点を確認してみてください。

  1. 対象の列は正しいかCells(Rows.Count, 1) の列番号(2つ目の引数)が意図した列になっているか確認しましょう。A列のつもりでB列を指定していた、というミスは意外とよくあります。
  1. データが入っていない列を指定していないか — 指定した列にデータが1つも入っていない場合、End(xlUp) は1行目を返します。変数に格納した値が「1」になっていたら、この可能性を疑ってみてください。
  1. 書式だけのセルが残っていないか — UsedRange や SpecialCells を使っている場合、過去にデータを削除したセルに書式が残っていると、実際のデータより大きな値が返ります。セルを選択して「クリア」(Delete キーではなく「すべてクリア」)を実行すると解消できます。

実務で使える!最終行取得の活用例

最終行を取得する方法がわかったら、実際のマクロで使ってみましょう。ここでは実務でよく使うパターンを2つ紹介します。

For文と組み合わせて全行を処理する

最終行取得の最大の活用場面は、For文と組み合わせたループ処理 です。

Sub 全行処理()
    Dim lastRow As Long
    Dim i As Long

    '--- A列の最終行を取得 ---
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row

    '--- 2行目から最終行までループ処理 ---
    For i = 2 To lastRow
        '--- B列に「処理済み」と入力する例 ---
        Cells(i, 2).Value = "処理済み"
    Next i

    MsgBox lastRow - 1 & "件のデータを処理しました"
End Sub

For i = 2 To lastRow とすることで、データが何行あっても自動で全行を処理してくれます。2行目から開始しているのは、1行目がヘッダー行(見出し行)であることを想定しているためです。

For文の使い方について詳しくは「【Excel VBA】For~Next文の使い方と実務で役立つ応用テクニック」で解説しています。ループ処理をもっと深く知りたい方はぜひ読んでみてくださいね。

変数の基礎から確認したい方は「【VBA】日本語は使える?変数の使い方とルールについて解説!!」も参考になりますよ。

最終列を取得する方法

行だけでなく、最終列 を取得したい場面もありますよね。考え方は最終行の取得とまったく同じです。

Dim lastCol As Long
lastCol = Cells(1, Columns.Count).End(xlToLeft).Column

違いは以下の3点です。

  • Rows.CountColumns.Count(最大列数を取得)
  • End(xlUp)End(xlToLeft)(左方向に探す)
  • .Row.Column(列番号を返す)

最終行と最終列を両方取得すれば、データ範囲全体を動的に指定できます。

Sub データ範囲を取得()
    Dim lastRow As Long
    Dim lastCol As Long

    lastRow = Cells(Rows.Count, 1).End(xlUp).Row
    lastCol = Cells(1, Columns.Count).End(xlToLeft).Column

    '--- データ範囲を選択する例 ---
    Range(Cells(1, 1), Cells(lastRow, lastCol)).Select

    MsgBox "データ範囲: A1:" & Cells(lastRow, lastCol).Address
End Sub

End プロパティで指定できる方向を一覧にしておきます。

定数方向用途
xlUp上方向最終行の取得
xlDown下方向先頭行からの探索(非推奨)
xlToLeft左方向最終列の取得
xlToRight右方向先頭列からの探索

まとめ

VBAで最終行を取得する3つの方法を紹介しました。

  • End(xlUp) — 最もおすすめ。特定の列の正確な最終行を取得できる
  • UsedRange — シート全体の使用範囲を取得。書式のみのセルも含む点に注意
  • SpecialCells — Ctrl+Endと同じ動作。最終行と最終列を同時に取得したいときに便利

迷ったら Cells(Rows.Count, 1).End(xlUp).Row を使えば間違いありません。

最終行の取得は、VBAでマクロを作るうえで避けて通れない基本テクニックです。最初のうちはコードを見ながら書いても問題ありません。何度も使ううちに自然と覚えられるので、焦らず実務のなかで身につけていきましょう。

For文やDo Loopと組み合わせれば、データの自動処理がぐっとラクになりますよ。まずは今回紹介したコードをコピーして、ご自身のマクロで試してみてください。

タイトルとURLをコピーしました