
エクセルVBAでデータ最終行取得方法で良い方法を教えてください。
データの行数、列数は不定。
最多のデータ行の列も不定。
この条件で、データ最終行を取得するにはどうすればよいでしょうか?
lastrow = ActiveSheet.Cells(ActiveSheet.Rows.Count, "A").End(xlUp).Row
では、A列の最終行に限定されます。
lastrow = ActiveSheet.Cells(1, "A").SpecialCells(xlLastCell).Row
では、列の限定はありませんが、一旦データ入力後、削除した部分まで入ってしまいます。
lastrow = ActiveSheet.UsedRange.Rows.Count
では、データ入力後、削除した部分まで入ってしまい、かつ、1行目など上部が空白の場合、不正確になります。
No.1ベストアンサー
- 回答日時:
それぞれの利点も欠点も分かっているなら後は
足りない部分を補うようにすればよいだけではないでしょうか。
・A列の最終行に限定されてしまう。
→列の指定を動的にして最大の行数を取得する。
例えばこんな感じ。ForでなくてもDoとかでも可です。
for x = 1 to ActiveSheet.Usedrange.Collumns.Count
temprow = ActiveSheet.Cells(ActiveSheet.Rows.Count, x).End(xlUp).Row
if temprow > lastrow then
lastrow=temprow
end if
next
結局他の部分にしても
最終行として取得したセル内が空白がどうかのチェックを行い、空白だったら行削除するとか、1行目など上部が空白の場合の例外処理をいれて対応しましょう。
No.11
- 回答日時:
こんにちは。
merlionXXさん。With ActiveSheet.UsedRange
lastrow = .Cells(.Count).Row
End With
>.Cells(.Count)って、UsedRange内の最後(右下)のセルという理解でよいのですね?
そうです。.Cells は、 左から右へ、上から下へと数を数えていきますから、最後のセルは、右端下になります。
#7 のbanker_Uさんのおっしゃるとおり、私も、SpecialCellsのLastCellは使いたいとは思います。でも、ワークシートに対する Refreshの方法が見当たらないのです。
最初Clearメソッドを使えばよいと思っていましたが、それだけではダメでした。オブジェクト自体を更新しないとダメなのですね。まだ、明確に、Refreshさせるための方法が見つかりません。ApplicationのWindowやダミーのブックで切り替えるなら出来そうですが、それは、あまりにも泥臭さすぎます。それと、ScreenUpDating ではダメだったわけです。
こんな方法も考えてみました。やはり、前回のような(自称)関西風です。
他にも、Find メソッドで、下から xlPrevious で、戻っていく方法もあると思います。
Sub FindLastRow2()
'最終行を探す
Dim r As Range
Dim MaxRow As Long
Dim ar As Variant
Dim buf As Variant
Set r = ActiveSheet.UsedRange
ar = Evaluate("(" & r.Address & "<>"""")*(ROW(" & r.Address & "))")
For i = r.Rows.Count To 1 Step -1
buf = WorksheetFunction.Index(ar, i, 0)
MaxRow = WorksheetFunction.Max(buf)
If MaxRow > 0 Then
Exit For
End If
Next
MsgBox "最後の行は、" & MaxRow
End Sub
No.10
- 回答日時:
#4 です。
本当にすみません、、、#9 で、、
>#5 です。何度もすみません。
>#5 だと正しく最終行を返さないので、差替えます。すみません。
は #4 の間違いです。Wendy02 さん、大変申し訳ありませんでした。以後、気をつけます。
No.9
- 回答日時:
#5 です。
何度もすみません。#5 だと正しく最終行を返さないので、差替えます。すみません。
それから、SpecialCells(xlCellTypeLastCell) は期待通り動作しない
場合があります。それは、ご質問文にあるとおり、
>一旦データ入力後、削除した部分まで入ってしまいます。
だからです。使う場合は、特に注意が必要ですね。
'Find Last Row Number
Function GET_LASTROWNUM(ByRef SH As Worksheet) As Long
Dim rngLASTROWS As Range, R As Range
Dim lngLAST_ROWNUM As Long
On Error Resume Next
Set rngLASTROWS = SH.UsedRange _
.Rows(SH.UsedRange.Rows.Count).Columns.Offset(1)
If Err.Number > 0 Then
GET_LASTROWNUM = SH.Rows.Count
GoTo Terminate
End If
On Error GoTo 0
For Each R In rngLASTROWS
lngLAST_ROWNUM = R.End(xlUp).Row
If lngLAST_ROWNUM > GET_LASTROWNUM Then
GET_LASTROWNUM = lngLAST_ROWNUM
End If
Next R
Terminate:
Set rngLASTROWS = Nothing
End Function
'Find Last Column Number
Function GET_LASTCOLNUM(ByRef SH As Worksheet) As Long
Dim rngLASTCOLS As Range, R As Range
Dim lngLAST_COLNUM As Long
On Error Resume Next
Set rngLASTCOLS = SH.UsedRange _
.Columns(SH.UsedRange.Columns.Count).Rows.Offset(0, 1)
If Err.Number > 0 Then
GET_LASTCOLNUM = SH.Columns.Count
GoTo Terminate
End If
On Error GoTo 0
For Each R In rngLASTCOLS
lngLAST_COLNUM = R.End(xlToLeft).Column
If lngLAST_COLNUM > GET_LASTCOLNUM Then
GET_LASTCOLNUM = lngLAST_COLNUM
End If
Next R
Terminate:
Set rngLASTCOLS = Nothing
End Function
No.8
- 回答日時:
#3です。
質問の意味が判りました。Sub test01()
r = Range("A1").SpecialCells(xlCellTypeLastCell).Row
c = Range("A1").SpecialCells(xlCellTypeLastCell).Column
MsgBox r
MsgBox c
mc = 1
mr = 1
'-----
For i = 1 To r
ct = Cells(i, "IV").End(xlToLeft).Column
If mc < ct Then mc = ct
Next i
MsgBox "最右列は" & mc
'-----
MsgBox "最下列は" & r
End Sub
で良いでしょう。
LastCellは、質問の意味での最下行を拾うと思う。セルを上から下、左から右に連番を振った最後(のセルのIndex値)だから。
それまでの全行について、データの最右列を探せばよい。
No.7
- 回答日時:
私の案はこんな感じ。
何と言ってもLastCellを使わない手は無いと思う。
その1:
一旦上書き保存してからLastCellを取得する。
その2:
Lastcell.Rowからデータの入っている列を探して上へ見ていく方法。
Function LastRow() As Integer
tempLastRow = ActiveCell.SpecialCells(xlCellTypeLastCell).Row
tempLastcolumn = ActiveCell.SpecialCells(xlCellTypeLastCell).Column
EndRowA = Range("A65536").End(xlUp).Row
LastRow = tempLastRow
Do While Cells(LastRow, tempLastcolumn).End(xlToLeft).Column = 1 _
And LastRow > EndRowA
LastRow = LastRow - 1
Loop
End Function
No.6
- 回答日時:
> UsedRange で得られる範囲がA1セルからではない場合に備え、
> どのような対応を組み込めばいいでしょうか?
#4 の関数はその点について、対応済みです。
Set UR = SH.UsedRange
For Each R In UR.Rows(UR.Rows.Count).Columns
の UR.Rows(UR.Rows.Count).Columns の部分で、UsedRange 内の
最下行を表す Columns コレクション(例えばB1:B20) が返されます。
この Columns コレクション 内を For Each ループさせて End(xlUp)
プロパティーで取得しています。
No.5
- 回答日時:
こんにちは。
Wendy02です。>データの行数、列数は不定。
>最多のデータ行の列も不定。
実際、このようなことに出会ったことがないです。列がどこまで使うという、イメージがないと、実際にどこに行くか分らないことになってしまいます。そして、End プロパティで探していくことになりますね。
>一旦データ入力後、削除した部分まで入ってしまいます。
ClearContents を使っているようです。そうする、書式データが残っています。Clearを使えば、Format は、削除されますが、画面(Window)を切り替えない限りは、残っています。
なお、これでは、正確にはとれませんが、
lastrow = ActiveSheet.UsedRange.Rows.Count
↓
With ActiveSheet.UsedRange
lastrow = .Cells(.Count).Row
End With
ということです。
まあ、KenKen_SPさんのと比較して、試してみてください。
これは、最終行のみです。(私は、こういうやり方を、関西風と呼んでいます。(^^;)
'------------------------------
Sub FindLastDataRow()
Dim r As Range
Dim myRow As Long
Dim myCol As Integer
Dim i As Long
Set r = ActiveSheet.UsedRange
myRow = r.Rows.Count
For i = myRow To 1 Step -1
If WorksheetFunction.CountA(r.Rows(i).Cells) > 0 Then
Exit For
End If
Next
MsgBox "最終行は、" & i
End Sub
ありがとうございました。
With ActiveSheet.UsedRange
lastrow = .Cells(.Count).Row
End With
勉強になりました!
.Cells(.Count)って、UsedRange内の最後(右下)のセルという理解でよいのですね?
No.4
- 回答日時:
こんにちは。
KenKen_SP です。関数化してみました。折角なので、最終列番号を取得する関数も作って
みました。汎用的に使えると思います。
ロジックは、UsedRange 内の各最終行・列でループさせて最大の行・列
番号をそれぞれ End プロパティーで取得する、、というものです。
基本的には #1 popesyu さんと同一の考え方ですが、UsedRange で得ら
れる範囲は必ずしも A列からではないことに注意が必要です。
UsedRange を使う理由は、調べる範囲(ループ回数)を最小限にして、
高速化するためです。
各関数の引数には Worksheet オブジェクトを渡します。使い方は、
コードの最後の方にサンプルコードを書いておきました。
'Find Last Row Number
Function GET_LASTROWNUM(ByRef SH As Worksheet) As Long
Dim UR As Range, R As Range
Dim lngLAST_ROWNUM As Long
Set UR = SH.UsedRange
For Each R In UR.Rows(UR.Rows.Count).Columns
lngLAST_ROWNUM = R.End(xlUp).Row
If lngLAST_ROWNUM > GET_LASTROWNUM Then
GET_LASTROWNUM = lngLAST_ROWNUM
End If
Next R
Set UR = Nothing
End Function
'Find Last Column Number
Function GET_LASTCOLNUM(ByRef SH As Worksheet) As Long
Dim UR As Range, R As Range
Dim lngLAST_COLNUM As Long
Set UR = SH.UsedRange
For Each R In UR.Columns(UR.Columns.Count).Rows
lngLAST_COLNUM = R.End(xlToLeft).Column
If lngLAST_COLNUM > GET_LASTCOLNUM Then
GET_LASTCOLNUM = lngLAST_COLNUM
End If
Next R
Set UR = Nothing
End Function
Sub SampleMacro()
MsgBox "最終行:= " & GET_LASTROWNUM(ActiveSheet)
MsgBox "最終列:= " & GET_LASTCOLNUM(ActiveSheet)
End Sub
わざわざ関数をつくってくださいましてありがとうございます。
UsedRange で得られる範囲がA1セルからではない場合に備え、どのような対応を組み込めばいいでしょうか?
No.3
- 回答日時:
Sub test02()
d = Range("A65536").End(xlUp).Row
r = Range("IV1").End(xlToLeft).Column
MsgBox d
MsgBox r
End Sub
でやれば途中空白行があっても最下行(行番号)、最右列を取れますが。
UsedRange、CurrentRegionもそれぞれ特徴は
ありますが。
何が困っているのかよくわからないですがとりあえず。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 追記する列を増やしたい 2つのデータを検索・照合して元データにないデータを下記マクロで商品名を追記し 9 2022/10/05 10:50
- Excel(エクセル) マクロで最終行から上に検索を逆にしたい 1 2022/05/17 18:27
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Visual Basic(VBA) 列と行の名前(重複あり)が交差するセルに、データを入力したい 2 2022/06/25 22:42
- Visual Basic(VBA) Sub 分けてソートして貼り付ける() Dim srcSheet As Worksheet Dim 6 2023/08/04 19:57
- Visual Basic(VBA) 数字が「0」の列を削除するため、下記のコードを実行しましたが、コンパイルエラーSubまたはFunct 3 2022/12/04 00:00
- Visual Basic(VBA) 列と行の名前(重複あり)が交差するセルに、データを入力したい 3 2022/06/12 11:17
- Excel(エクセル) B列に文字がはいったらA列に数字が入るマクロードを完成させたい 4 2023/04/21 01:58
- Visual Basic(VBA) VBA 行削除した連番 4 2023/06/27 16:00
- Visual Basic(VBA) 最終行の指定について教えてください。 複数シートを1シートへまとめる下記マクロでは各シートの6行目を 1 2022/10/04 18:37
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「段」と「行」の違いがよくわ...
-
列方向、行方向の定義
-
EXCELを最大にて開いた際、特定...
-
VBAで結合セルを転記する法を教...
-
【Excel VBA】列幅の設定
-
VBA 列の削除を何回か繰り返す...
-
エクセル マクロ 指定範囲内...
-
VBA 配列について
-
エクセルマクロでオートフィル...
-
列を1つずつ非表示にしたい
-
エクセルマクロ
-
マクロセルの値によってセルの...
-
エクセルVBAで値のカウントをし...
-
エクセルで最初の行や列を開け...
-
該当データのみを抽出したい。
-
゙逆゙ のやつってどうすれば ゙順...
-
エクセルのソートで、数字より...
-
LEFT関数とIF関数の組み合わせ...
-
Excelの計算式で質問です。
-
エクセル 任意の列数で分割する...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「段」と「行」の違いがよくわ...
-
エクセルで離れた列を選択して...
-
VLOOKUPの列番号の最大は?
-
LEFT関数とIF関数の組み合わせ...
-
VBA 指定した列にある日時デー...
-
Excelの行数、列数を増やしたい...
-
CSVファイルの「0落ち」にVBA
-
列方向、行方向の定義
-
エクセルのソートで、数字より...
-
Excel文字列一括変換
-
VBAで別ブックの列を検索し、該...
-
エクセル マクロ 範囲の値を上...
-
VBAで重複データを合算したい(...
-
エクセル マクロ 範囲指定で...
-
VBAで結合セルを転記する法を教...
-
エクセルで最初の行や列を開け...
-
エクセルマクロPrivate Subを複...
-
土日の列幅の自動変更を教えて...
-
最近急にVBAの処理速度が遅くな...
-
エクセルでセル12個間隔で合...
おすすめ情報