2018年10月20日土曜日

最終行の取得

最終行の取得は、
Cells(Rows.Count, 1).End(xlUp).Row
をしょっちゅうググって(暗記する気がないせい)使うわけですが、サンプルを見るたびにいちいちちょっと気になることが2点あります。
(1) Rows は Range オブジェクトだよね~ と、
(2) なんでサンプルコードに「1」とか列番号を決め打ちするかね、の2点です。

(1)は、シートを移動しないで別のシートのデータ範囲の底の行を取得する場合、例えば、
Worksheets("表紙").Select
With Worksheets("データ")
    BtmRow = .Cells(Rows.Count, 1).End(xlUp).Row
End With
としてしまうと、 Rows.Count は表紙シートの底の行番号を返すんじゃね?それでいいんだっけ?って気になるわけです。
どのシートも底の行数は同じなので特に影響はないですが、気持ち悪いので、.Rows.Count とドットを付けといた方が良いと思います。

(2)は、行を一意にするキーとなる列か、データに空白がない列を指定すればいいわけですが、但し、例えば、表の底に総計行が追加されているような場合は、その行を含めるのか含めないのかによって選択する列が変わるわけです。
なので、表の底に追加されている総計行を含めるのであれば、総計行のラベルの列か総計値の列を指定するので、シートによってケースバイケースなわけです。

サンプルコード


例1のように、シート情報と列番号をパラメータとして渡してどのシートでも使える関数を書いて
最終行番号=最終行("管理表",5)
とか呼び出せば良いわけですが、
'【例1】=================================================================='
    Function 最終行( _
        ByVal pWorksheetName As String, _
        ByVal pColumnNo As Long _
    ) As Long
'========================================================================='
        If pColumnNo <= 0 Then pColumnNo = 1
        With Worksheets(pWorksheetName)
            最終行 = .Cells(.Rows.Count, pColumnNo).End(xlUp).Row
        End With
    End Function
でも、どうせシートによって列構成も違うし、キーとなる列も違うわけです。なので、各シート別に関数を書いて、できれば Date() みたいに定数のように使えると便利だよね~と思うので、例2のようにシート名やデフォルト列を決め打ちして
最終行番号=管理表最終行()
と呼び出せるように、シート別の関数をシートの数だけ書いちゃえば良いと思います。
'【例2】=================================================================='
    Function 管理表最終行( _
        Optional ByVal pColumnNo As Long _
    ) As Long
'========================================================================='
        Const DefaultColumnNo As Long = 5 'デフォルトの列を指定しておく'
        If pColumnNo <= 0 Then pColumnNo = DefaultColumnNo
        With Worksheets("管理表") 'シート名も決め打ち'
            管理表最終行 = .Cells(.Rows.Count, pColumnNo).End(xlUp).Row
        End With
    End Function

2018/12/29:言葉足らずな感じのところを少し手直ししました

0 件のコメント:

コメントを投稿