VBAで最終行を取得する方法を紹介します。
また最終行と最終列の取得方法は、ほとんど同じなので一緒に紹介します。
取得するときに発生するエラーについても紹介していますので、うまく取得できない場合の参考にしてみてください。
目次
VBA最終行・最終列を取得する
VBAでは最終行・最終列を取得する方法がいくつかあります。
今回は4つ紹介しますが、基本はEndプロパティでの取得方法がわかりやすいです。
Endプロパティで取得する
Sub LastRow1()
'Endプロパティを使用して最終行を取得
MsgBox Cells(Rows.Count, 1).End(xlUp).Row
End Sub
セルを手動操作したときのイメージをもとに取得する方法です。
A1セルから最終行に移動するには、ショートカットで「Ctr + ↓」になります。
ただし、途中でセルに空白があるとそこで止まってしまうので、逆から移動します。
ショットカットだと「Ctr + ↑」です。
これをVBAで書くと
Ctr + ↓ → End(xlDown)
Ctr + ↑ → End(xlup)
となります。
Cells(Rows.Count, 1)の部分が上の移動する元の位置のセルを表します。
Rows.Coumtとは、シートの最終行のことです(2007以降1048576行、2003は65536行)。
つまり、Cells(Rows.Count, 1).End(xlup)で、1列目の最終行から上に移動したときのセルということになります。
2列目の最終行を取得したい場合は「1」を「2」にすれば大丈夫です。
今回は最終行(最終列)を知りたいのですが、Cells(Rows.Count, 1).End(xlup)で取得できるのはセルの場所(A5セルとかA10セル)だけになります。
そこで取得できたセルの行を取得するには、Rowプロパティを使用すればOKです。
これで最終行の取得ができます。
最終列の場合も同じ要領で取得ができます。
Sub LastColumn1()
'Endプロパティを使用して最終列を取得
MsgBox Cells(1, Columns.Count).End(xlToLeft).Column
End Sub
EndとCellsの()の内容が変更になり、列を取得するので、RowをColumnに変更します。
列の場合は、右から左に移動することで最終列を取得できるので「xLToLeft」を使用します。
Ctr + → : End(xlToRight)
Ctr + ← : End(xlToLeft)
Columns.Countは、Rows.Countと同じで、最終列を(16384列)表しています。
CurrentRegionプロパティで取得する
Sub LastRow2()
'CurrentRegionプロパティを使用して最終行を取得
MsgBox Range("B2").CurrentRegion.Row + Range("B2").CurrentRegion.Rows.Count - 1
End Sub
CurrentRegionは現在の領域を表すRangeを返します。
もう少し簡単に言うと、選択されているセルが含まれる部分の表のRangeオブジェクトを返します。
表なのでRangeオブジェクトにはRange(”B2:E17″)のような選択範囲が取得されます。
この表は空白セルに囲まれた範囲を取得します。
上の画像でいうと、A列とF列、1行目と18行目の空白に囲まれた範囲を取得する、ということになります。
今回はRange(“B2”)を起点に選択しています。
Range(“B2”).CurrentRegion.Rowは、選択範囲の最初の行番号を、Range(“B2”).CurrentRegion.Rows.Countは取得した範囲の行数を取得しています。
上の画像でいうと、Range(“B2”).CurrentRegion.Rowは「2」、Range(“B2”).CurrentRegion.Rows.Countは「16」になります。
マイナス1しているのは、行番号に行数を足すと1多く足していることになっているので、それを減らすために「-1」を最後に付けています。
UsedRangeプロパティで取得する
Sub LastRow3()
'UsedRangeプロパティを使用して最終行を取得
MsgBox ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count - 1
End Sub
CurrentRegionとほぼ同じですが、UsedRangeプロパティはRangeではなくシートのプロパティなので、ActiveSheetのようにシート名で指定します。
シートのプロパティですので、表が
SpecialCellsプロパティで取得する
Sub LastRow4()
'SpecialCellsプロパティを使用して最終行を取得
MsgBox Cells.SpecialCells(xlCellTypeLastCell).Row
End Sub
SpecialCellsプロパティのxlCellTypeLastCellは使用している最終セルを取得します。
今回の例ではRange(“E17”)が最終セルになります。
そのセルの行を取得するので、Rowを最後に付けています。
最終行の次の行を取得するには?
最終行の取得方法は以上ですが、実際に使用する場合は、最終行の次の行から値を入力するというような使い方になると思います。
では最終行の次の行を取得するにはどうすれば良いかというと、単純に「1」を足せば大丈夫です。
Endプロパティの例だと、
Cells(Rows.Count, 1).End(xlUp).Row + 1
これだけでOKです。
最終行・最終列が取得できない原因と対策
上記の方法で最終行が取得できますが、それでもうまく取得できない場合があります。
その原因と対策をいくつか紹介します。
途中で空白セルが含まれている
表形式で途中に空白のセルが入ってしまうと、CurrentRegionではうまく取得できません。
上記のVBAコードをこの表で実行すると「9」が返ってきます。
CurrentRegionは空白セルに囲まれた表を取得するという特徴があるので、空白のセルが入ってしまうと途中で取得できなくなってしまいます。
この場合は、空白セルを埋めるか、Endプロパティなど他の取得方法を利用して回避できます。
オーバーフローのエラーが出る
最終行を取得する場合、2007以降なら1048576行まであります。
例えば、最終行を変数に代入する場合、データ型が「Integer」だとセットできる範囲を超えてしまう可能性があります。
そうならないためにはデータ型を「Long」に変更して置く必要があります。
Sub LastRow5()
'Endプロパティを使用して最終行を取得
Dim lastRow As Long '←ここを「Integer」ではなく「Long」にする
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
MsgBox lastRow
End Sub
罫線がある
取得する表に罫線がある場合、UsedRangeやSpecialCellsは罫線のあるセルも含めてしまいます。
上記のUsedRangeのコードをこの表で実行すると「18」が返ってきます。
罫線しかない空白セルがある場合は、CurrentRegionやEndプロパティを使用することで回避できます。
非表示の行がある
非表示の行がある場合、EndプロパティとSpecialCellsプロパティは非表示を無視して最終行を取得します。
この表は16行が非表示になっていますが、A16セルに値が入力されています。
でも、上記のEndプロパティを使ったVBAコードを実行すると「15」が返ってきます。
つまり、見た目のままの最終行が取得されることになります。
UsedRangeプロパティとCurrentRegionプロパティは非表示の行に値が含まれているとその行も範囲に含みます。
ただ、最終行を取得する場合は、非表示があると分かりづらくなるので基本は表示しておくようにしましょう。
オートフィルタがかかっている
オートフィルタがかかっている場合、UsedRangeプロパティとCurrentRegionプロパティ
は、見た目の行番号ではなく実際に入力されている行番号の最終行を取得します。
上の表だと「17」が取得されます。
EndプロパティとSpecialCellsは見た目の行番号を取得するので「16」になります。
こちらも非表示と同様に、誤解しやすいのでオートフィルタは解除しておくほうがよいでしょう。
セルが結合されている
最終行がセルで結合されている場合、Endプロパティでは結合されている一番最初の行を取得します。
上の表の場合、「15」が取得されます。
その他のプロパティは「16」が取得されます。
結合セルはVBAで扱うときに厄介な存在になるので、なるべくは解除しておくほうが良いです。
まとめ
VBAで最終行と最終列を取得する方法とエラー対策をまとめて紹介しました。
表の最終行を取得することは、自動化では欠かせないことなので、何度も書くことになると思います。
どの方法でも取得はできますが、基本はEndプロパティを抑えておけば大丈夫です。
その上で、エラーや思ったように取得できないときは、表の形式に問題があるかもしれないので、表を確認するようにしてみてください。