【Excel VBA】最終行・最終列を自動取得する方法|表が増えても壊れないマクロの基本テク

Excel関係

Excel VBAで表を操作するマクロを書いていると、「行数や列数が変わるたびにコードを直す」という悩みに必ずぶつかります。あらかじめ範囲を決め打ちしたコードは、データが増えた瞬間に処理漏れが起きたり、逆に空白行まで無駄に処理してしまったりします。この記事では、どんな表サイズにも自動で対応できる「最終行・最終列の取得方法」を、図解を交えて解説します。

「決め打ち範囲」がなぜ危険なのか

マクロ初心者がまずやりがちなのが、Range("A1:A100")のように処理範囲を数字で固定してしまう書き方です。この方法は一見シンプルですが、表の行数が変わった瞬間に破綻します。たとえばデータが150行に増えれば101行目以降が処理されずに取りこぼされますし、逆に実際のデータが50行しかなければ、51〜100行目という「何もない範囲」まで無駄にループしてしまい、処理速度の低下やエラーの原因になります。

実務で扱う表は、日々の入力によって行数も列数も変動するのが当たり前です。だからこそ、マクロの中で「今、表は何行目・何列目まであるのか」をそのつど自動で調べる仕組みが欠かせません。この仕組みさえ作っておけば、表がどれだけ増減しても同じマクロがそのまま使い続けられます。

最終行を取得する定番コード「Cells(Rows.Count, 1).End(xlUp)」

最終行を取得する最も定番の書き方が、以下のコードです。

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

この一行は、3つの動きを組み合わせています。まずRows.Countでシートの最大行番号(104万8576行目)を取得し、Cells(Rows.Count, 1)でA列の一番下のセルを指定します。そして.End(xlUp)が、そのセルを起点にキーボードの「Ctrl+↑」を押したときと同じ動きをして、データが入っている一番下の行まで一気にジャンプしてくれます。

下の図は、この「シート最下部から上に向かってデータを探し当てる」動きをイメージ化したものです。空白セルを飛び越えて、最初にデータが見つかった行で止まる様子がわかります。

Cells(Rows.Count,1).End(xlUp)でシート最下部からデータのある最終行まで上にたどり着く動きを示す図解

最終列も同じ考え方で取得できる

行だけでなく、列数が変動する表もよくあります。最終列を取得する場合は、行と列の関係を入れ替えた次のコードを使います。

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

Columns.Countはシートの最大列番号(1万6384列目)、End(xlToLeft)はキーボードの「Ctrl+←」に相当する動きです。1行目の一番右のセルを起点に左方向へ進み、最初にデータが見つかった列で止まります。最終行の取得と考え方はまったく同じで、「探す起点」と「探す方向」が違うだけだと覚えておくと理解しやすいでしょう。

最終行と最終列を両方取得できれば、表全体の範囲を動的に組み立てられます。次の図は、行数・列数がどちらも変動する表に対して、この2つの値を組み合わせてデータ範囲全体を自動認識する仕組みを表したものです。

最終行と最終列を組み合わせて表全体のデータ範囲を自動認識する仕組みを示す図解

実務で使うときの注意点と活用例

この方法にはひとつだけ注意点があります。それは「表の途中に空白セルがある」場合です。End(xlUp)は最初に見つかった空白で止まる性質があるため、たとえばA列の途中に空白セルが挟まっていると、その空白の直前で処理が止まってしまい、実際の最終行より手前の行を「最終行」と誤認識することがあります。この対策としては、絶対に空白にならない列(IDや連番の列など)を基準に最終行を取得するのが実務上のコツです。

最終行を取得する方法としては、Range("A1").CurrentRegionActiveSheet.UsedRangeを使う書き方もよく紹介されますが、実務ではあまりおすすめできません。UsedRangeは「過去に一度でも書式やデータが入ったことのあるセル」まで含んでしまうため、行を削除してもその範囲が縮まらず、実際のデータより広い範囲を最終行と誤認識することがあるからです。その点、End(xlUp)End(xlToLeft)は「今まさにデータが入っているセル」だけを見て判定するため、削除・追加を繰り返す表でも安定して動作します。

取得した最終行・最終列は、そのままループ処理や範囲指定に活用できます。たとえば次のように書けば、表全体を範囲としてまとめて扱えます。

Dim lastRow As Long, 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

このように「表の右下端」を自動で特定できれば、集計・転記・書式設定など、あらゆる自動化マクロの土台として使い回せます。For Nextループの終了条件にlastRowを使ったり、他シートへの転記先をlastColから自動計算したりと、応用範囲は非常に広いです。今回紹介した2行は、実務でExcelマクロを書く上でほぼ必ず登場する基本テクニックです。最初はコードの意味を丸暗記でも構いませんので、まずはご自身の表にコピーして動かしながら、少しずつ体に馴染ませてみてください。

コメント

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