Public Function lastRow(Byval ws As WorkSheet,Byval colName As String)As Long
Dim val As Variant
val = colName
If IsNumeric(val) Then val = CLng(val)
ws.Cells(Rows.Count,val).End(xlUp).Row
End Function
これを
Dim 最終行番号 As Long
最終行番号 = lastRow(シートの変数,"アルファベットか列番号")
とすれば、指定のシートの指定の列の最終行番号を取得できます
For r = 2 To lastRow(シートの変数,"アルファベットか列番号")
Next r
でも問題ないです。
もうあっちこっちに
ws.Cells(Rows.Count,"アルファベットか列番号").End(xlUp).Row
と書かなくて済みます。
これで読者の皆さんはFanctionの正しい使い方をマスターできました。
Functionを理解している、だけでもあなたはもうVBA中級者~上級者です。
Cells(Rows.Count,"A").End(xlUp).Rowの意味について。
このコードのそれぞれの意味が分かれば、ExcelをVBAで扱う上でのオブジェクトの階層が理解できて、わからないことがあれば自分で調べたり、検討が付くようになって、作業時間が大幅に減少します。約束します(私は長らく理解していなかったのでただの暗記になっていました)。
'「Worksheet.Cells プロパティ」(シートの指定が抜けているのでアクティブなシートの)セルの場所を取得する
Cells
'Cellsプロパティーの「第一引数」(指定の範囲の行数を数える。今回の場合は、無指定なので、つまり104万行目)
Rows.Count
'Cellsプロパティーの「第二引数」指定の列名(列番号)の
,"A")
'「Range.End プロパティ」コントロールキー+↑キーで該当するセル(Rangeオブジェクト)を取得
.End(xlUp)
'「Range.Row プロパティ」該当したセルの行番号(プロパティー、行番号)
.Row
つまりこのコードの意味する所は
(シートが無指定なので)アクティブシートの、指定の列の、104万行目からショートカットキーで上に移動した、空白でないセルのたった「行番号」を取得するだけのコードだったのです。
しかもExcelのオブジェクトの階層は
WorkBook.WorkSheets.Range
なので
「シートの.全てのセルの.行を数える」だったのです。(果たして104万行目まで必要でしょうか?)。
もし読者の皆さんが「せいぜい1000行くらいまでしか使用しないな」というのであれば、
ws.Range("A1000").End(xlUp).Row
でも十分なのです。
もっと言うと、指定の範囲内でループしたい、指定の範囲の行数を数えたいのであれば、
WorkBook.WorkSheets.Range.Cellsプロパティー を使用するべきなので
'仮にこの範囲だと仮定
Set rng = ws.Range("C10:F100")
For r = 1 to rng.Rows.Count
'指定した範囲の中の単一セルを指定
rng.Cells(r,1).Value
'指定の範囲の1行
rng.Rows(r)
Next r
でいいのです。