開始日(一番古い日付)を求める
とある日付列の中から、開始日(一番古い日付)を求めたくなった。
これについて職場で話し合ったところ、三つの方法が提案された。
そこで、いつもの「なんちゃって個人情報」を題材に、その三つの案を
比較してみよう。
1.一つずつ比較
まず一行目の日付を、仮に開始日とする。
そして一行ずつ日付を確認し、開始日より小さければ置き換える。
Sub GetStartDate() ' なんちゃって個人情報テーブル。 Dim Tb As ListObject Set Tb = ActiveSheet.ListObjects(1) ' 開始日。 Dim StartDate As Date ' テーブルの一行目を仮の開始日とする。 StartDate = Tb.ListColumns("誕生日").DataBodyRange.Cells(1) ' ループ用変数。 Dim r As Range ' 比較して小さい方を開始日と置き換える。 For Each r In Tb.ListColumns("誕生日").DataBodyRange If r <= StartDate Then StartDate = r End If Next Debug.Print StartDate End Sub
考え方としては、一番素直だと思う。
2.並び替え
昇順で並び替えて一番最初の日付が、一番古い日付だ。
表の並びを変更したくない場合、一旦配列に入れる方法がある。
Sub GetStartDate() ' なんちゃって個人情報テーブル。 Dim Tb As ListObject Set Tb = ActiveSheet.ListObjects(1) ' 日付を収めた配列。 Dim arr As Variant arr = Tb.ListColumns("誕生日").DataBodyRange ' このままでは二次元配列(複数行1列)のため、一次元配列に変換する。 arr = WorksheetFunction.Transpose(arr) ' 一次元配列をソート。 Dim aryList As Object Set aryList = CreateObject("System.Collections.ArrayList") Dim a As Variant For Each a In arr Call aryList.Add(a) Next Call aryList.Sort arr = aryList.ToArray Debug.Print arr(0) End Sub
一次元配列のソート方法を知らないと使えないし、結構な手間もかかっている。
3.Min関数
範囲に対してMin関数を用いる、という方法。
Sub GetStartDate() ' なんちゃって個人情報テーブル。 Dim Tb As ListObject Set Tb = ActiveSheet.ListObjects(1) Dim StartDate As Date StartDate = WorksheetFunction.Min(Tb.ListColumns("誕生日").DataBodyRange) Debug.Print StartDate End Sub
一番短い。先の二つが何だったのかというぐらい、シンプルで分かり易い。
ということで、満場一致で、案3に決定したのでした。
参考まで。