開始日(一番古い日付)を求める

とある日付列の中から、開始日(一番古い日付)を求めたくなった。
これについて職場で話し合ったところ、三つの方法が提案された。
f:id:Infoment:20200926165020p:plain

そこで、いつもの「なんちゃって個人情報」を題材に、その三つの案を
比較してみよう。
f:id:Infoment:20200926165228p:plain

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に決定したのでした。

参考まで。