Excel VBAで最終行の行番号や値、最終行の次に入力したいときはないでしょうか。
けど、そんな中で悩むことは、
・途中に空行があると、思った行と違う結果になってしまう
・毎回データの末尾を目で探して手入力するのが手間
・End(xlDown)やUsedRangeとの使い分けがわからない
ですよね。
今回はそんなお悩みを解決する
についてまとめます!
完成イメージ
最終行を扱うときは、どの方法で最終行を調べるかで結果が変わります。
今回は
・Cells(Rows.Count, 1).End(xlUp).Row で最終行の行番号を取得する方法
と
・同じ書き方の .Value で最終行の値を受け取る方法
をゴールにします。
あわせて、最終行の次(最終行+1)に自動で入力する方法まで扱えるようにします。

上の画像が完成形です。11行目が最終行で、その次の12行目に新しい日報が自動で追記されています。
なお、End(xlDown)・UsedRange・CurrentRegion との違いと、うまくいかないときの対処法(トラブルシュート)もあわせてご紹介します。
もくじ
STEP1. 日報データを用意する
まずは最終行を調べたい日報データを用意します。
1行目が見出しで、A列が日付、B列が商品、C列が数量です。
データは2行目から11行目まで入っていますが、6行目だけは空行にしてあります。
この空行があることが、あとで方法を選ぶときのポイントになります。

下の表をコピーして、Excelのシートに貼り付けるとそのまま試せます。
| 日付 | 商品 | 数量 |
|---|---|---|
| 2026/10/01 | ノートA | 12 |
| 2026/10/02 | ボールペンB | 30 |
| 2026/10/03 | コピー用紙 | 5 |
| 2026/10/04 | ファイルC | 8 |
※ 数式で求める列は空にしています。すでに値が入っている列はそのまま残して試せます。
STEP2. 最終行の行番号を取得する(End(xlUp).Row)
最終行の行番号を調べる基本の書き方がこちらです。
シートの一番下の行から上に向かって、値のあるセルを探します。
基準は日付が入っているA列にします。
Sub GetLastRow()
Dim lastRow As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
MsgBox "最終行は " & lastRow & " 行目です"
End Sub
下からたどると、値がある最後のセルは11行目でした。
そこで .Row を使うと、最終行の行番号 11 が数値で返ります。
6行目に空行があっても、下から数えるので影響を受けません。
カンタンですね。

STEP3. 最終行の値を取得する(End(xlUp).Value)
行番号だけでなく、最終行に入っている値そのものを取りたいときは .Row を .Value に変えるだけです。
コードはこちらです。
Sub GetLastValue()
Dim lastVal As Variant
lastVal = Cells(Rows.Count, 1).End(xlUp).Value
MsgBox "最終行の値は " & lastVal & " です"
End Sub
マクロを実行すると、最終行の2026/10/11 が表示されます。
覚え方はカンタンで、「行番号が欲しければ .Row、値が欲しければ .Value」です。
行番号を先に取ってから名前に使う、といった使い分けができるようになります。

STEP4. 最終行の次に入力する
最終行が分かれば、その次の行に自動で入力することもできます。
最終行に1を足した行(今回は12行目)に、新しい日報を書き込みます。
コードはこちらです。
Sub AddNextRow()
Dim lastRow As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
Cells(lastRow + 1, 1).Value = Date
Cells(lastRow + 1, 2).Value = "ボールペンB"
Cells(lastRow + 1, 3).Value = 18
End Sub
マクロを実行すると、空いていた12行目に日付・商品・数量が入りました。
データの末尾を毎回目で探さなくても、自動で最新行の下に追加されます。
ボタンに登録しておけば、日々の入力の手間も記入漏れのミスも減らせますね。

STEP5. End(xlDown) だと空行で止まる
同じ「最終行を調べる」でも、上から下へ探す Range.End(xlDown) を使うと結果が変わります。
今回の表は6行目が空行なので、上からたどると5行目で止まってしまいます。
コードはこちらです。
Sub BadLastRow()
Dim lastRow As Long
' 6行目が空行なので、5行目で止まってしまう
lastRow = Range("A1").End(xlDown).Row
MsgBox "End(xlDown) が返すのは " & lastRow & " 行目です"
End Sub
マクロを実行すると、返ってくるのは11ではなく5です。
そのまま「最終行+1」に入力すると6行目に書き込んでしまい、データが途中で分断されてしまいます。
空行がある表では、上から数える方法は使わないと覚えておきましょう。

STEP6. UsedRange と CurrentRegion で範囲を取る
最後に、表の範囲をまとめて取りたいときの2つの方法を確認します。
1つめは UsedRange で、そのシートで使われた範囲を返します。
2つめは CurrentRegion で、基準セルを含む空白行・空白列で囲まれた一塊を返します。
ここで、13〜15行目に値は入れず書式だけを設定してみました。
Sub TableRange()
MsgBox "UsedRange は " & ActiveSheet.UsedRange.Address
MsgBox "CurrentRegion は " & Range("A1").CurrentRegion.Address
End Sub
UsedRange は書式だけの行も「使われた」とみなすため、A1:C15 を返します。
実際のデータは12行目までなので、UsedRange は実際より大きく返ることがある点に注意です。
一方の CurrentRegion は空白行で区切られるため、今回は A1:C5 までしか返りません。
表の範囲を取りたいときは、空行が無いことを確認してから使いましょう。

4つの方法の比較
最終行や範囲を調べる方法の違いを表にまとめました。
返すものが違うので、使いどころも変わります。
| 方法 | 返すもの | 今回の結果 | 向いている場面 |
|---|---|---|---|
| Cells(Rows.Count, 1).End(xlUp).Row | 下から見た最終行の行番号 | 11 | 最終行の取得・次の行への入力 |
| Range(“A1”).End(xlDown).Row | 上から見た連続データの行番号 | 5 | 空行が無いと分かっている表 |
| UsedRange | シートで使われた範囲全体 | A1:C15 | シート全体のデータ量の把握 |
| CurrentRegion | 空白行・列で区切られた一塊 | A1:C5 | 表の範囲をまとめて取得 |
最終行を調べるときは、下から数える Cells(Rows.Count, 列).End(xlUp) が基本です。
上から数える End(xlDown) や、空白で区切られる CurrentRegion は、途中に空行があると手前で止まってしまいます。
「行番号が欲しいなら .Row」「値が欲しいなら .Value」とセットで覚えておきましょう。
迷ったら 一番下から上へ(End(xlUp))と覚えておけば、空行があっても安心ですよ。
うまくいかないときの対処法(トラブルシュート)
実際に試すと、思ったように動かないこともあるかもしれません。
よくあるつまずきと対処法をまとめました。
| 症状 | 原因 | 対処 |
|---|---|---|
| End(xlDown) が途中の行番号を返す | データの途中に空行がある | 下から数える Cells(Rows.Count, 列).End(xlUp).Row を使う |
| UsedRange が実際より大きい | 書式だけ設定したセルや消し忘れたセルも「使用済み」に残る | 不要な行・列を削除して上書き保存し、開き直す |
| 列によって最終行が違う | 基準にする列がずれている(列指定の間違い) | 日付やキーの列を基準にし、Cells(Rows.Count, 1) の「1」を確認する |
| シートの最大行を間違える | 最終行を 65536 などの古い値で書いてしまう | 定数で書かず、必ず Rows.Count を使う(現在は 1,048,576 行) |
| 最終行が 1048576 になる | 数式の =”” が下の行まで入り、空に見えても値がある | 余分な数式を消す/空白に見えるセルの中身を確認する |
| 1件しかない表で最終行が2になる | 見出し行の下にデータが無く、A1から数えてしまう | 基準列と開始位置を確認し、見出し行を数えないようにする |
関数の説明
今回使う3つ(End・UsedRange・CurrentRegion)の概要です。
どれも最終行まわりでよく使うものなので、違いを押さえておきましょう。
End(Range.End プロパティ)
| 書式 | オブジェクト.End(方向) ※方向は xlUp / xlDown / xlToLeft / xlToRight |
|---|---|
| できること | 基準セルから指定した方向へ、データが続く限り移動した先のセルを返します。 |
| 戻り値 | Rangeオブジェクト(.Row で行番号、.Value で値、.Address で番地) |
| こんなときに | 下から数えて最終行を求めたいとき。Cells(Rows.Count, 列).End(xlUp) が定番です。 |
| 注意 | 途中に空行があると、そこを境に止まります。最終行の取得は End(xlDown) ではなく下から数える End(xlUp) が安全です。 |
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
UsedRange(プロパティ)
| 書式 | ActiveSheet.UsedRange / Worksheet.UsedRange |
|---|---|
| できること | そのシートで「使われた範囲」をまとめて表すRangeを返します。 |
| 戻り値 | Rangeオブジェクト(.Address/.Rows.Count/.Row で確認) |
| こんなときに | シート全体のデータ量をざっくり把握したいとき。 |
| 注意 | 書式だけのセルや、値を消したあとのセルも「使用済み」として残るため、実際のデータより大きく返ることがあります。 |
MsgBox ActiveSheet.UsedRange.Address
CurrentRegion(プロパティ)
| 書式 | Range(“A1”).CurrentRegion |
|---|---|
| できること | 基準セルを含む、空白行・空白列で囲まれた一塊(連続した表)を返します。 |
| 戻り値 | Rangeオブジェクト(.Address/.Rows.Count で確認) |
| こんなときに | 表全体の範囲をまとめて取得したいとき(並べ替え・罫線・コピーなど)。 |
| 注意 | 途中に空行・空列があると、そこで区切られて範囲が狭くなります。空行を含む表では結果を確認しましょう。 |
Set tbl = Range("A1").CurrentRegion
完成
11行目が最終行と正しく判定され、その次の12行目に新しい日報が追記されました。
思ったとおりに動きましたか?
空行があっても、下から数える End(xlUp) なら最終行を見失いません。
最終行が自動で分かれば、入力の手間も記入漏れのミスもぐっと減らせます。

さいごに
いかがでしょうか。
今回は、
についてまとめました。
まずは今回のサンプル表で、ぜひ一度試してみてください。
最終行を調べるときは、上から数える End(xlDown) ではなく、下から数える Cells(Rows.Count, 列).End(xlUp) を使ってみてくださいね。
また、他にも便利なExcelの時短テクニックがありますので、よろしければご参照頂ければと思います。
ぜひ試してみてください。














コメントを残す