t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

VBA ファイル名に入ったyyyymmdd形式の日付をDate型として取り出すための関数を自作

VBAでDate型の値をyyyymmdd形式にするのはすこぶる簡単だ。
format関数を使えばよい。

たとえば今日の日付をもとに、「sample_yyyymmdd.log」というログファイルの名前を出力したかったら、次のように書けば良い。

Sub ログ名を出力()
    Debug.Print "Sample_" & Format(Date, "yyyymmdd") & ".log"
End Sub

yyyymmddは実際には日付が入る。たとえば今日なら「Sample_20161215.log」。

さて、日付から特定書式の文字列へ変換するにはFormat関数が使えることが分かった。

ではその逆はどうか。

たとえば「Sample_20161215.log」という文字列から「2016/12/15」というDate型のデータを取り出したいケースである。

愚直にやると、こんなコードになる。

Sub ログ名から日付を出力()
    Dim str As String: str = "Sample_20161215.log"
    Dim yyyy As Long: yyyy = Mid(str, 8, 4)
    Dim mm As Long: mm = Mid(str, 12, 2)
    Dim dd As Long: dd = Mid(str, 14, 2)
    Debug.Print DateSerial(yyyy, mm, dd)
End Sub

まあこれでも良いんだけど、Mid関数に渡すStartを計算する必要があり、間違いやすいポイントなのでもう少しなんとかしたい。

そこで、文字列を指定サイズで切り分けて配列で返す関数「SplitBySizes」を作ってみた。
もともとVBAには組み込みで文字列を切り分けるためのSplit関数が用意されているが、あれと同じようなイメージ。
Splitは区切り文字で切り分けるが、SplitBySizesは文字数を基準に切り分ける。

使い方は、SplitBySizes(文字列, 文字数, 文字数, 文字数…)という風に文字数をParamArrayで渡してやる。するとその文字数分が配列の要素になる。

具体的には、arr = SplitBySizes("Sample_20161215.log", 7,4,2,2)とすると、arrには以下のような配列が格納される。

配列 要素 文字数
arr(0) "Sample_" 7
arr(1) "2016" 4
arr(2) "12" 2
arr(3) "15" 2

SplitBySizesのコードはこちら。

Function SplitBySizes(str As String, ParamArray sizes())
    Dim cursor As Long: cursor = 1
    Dim ret(): ReDim ret(LBound(sizes) To UBound(sizes))
    Dim i
    For i = LBound(ret) To UBound(ret)
        ret(i) = Mid(str, cursor, sizes(i))
        cursor = cursor + sizes(i)
    Next
    SplitBySizes = ret
End Function

これを使って日付を取り出すコードはこちら。

Sub ログ名からSplitBySizesを使って日付を出力()
    Dim arr: arr = SplitBySizes("Sample_20161215.log", 7, 4, 2, 2)
    Dim d As Date: d = DateSerial(arr(1), arr(2), arr(3))
    Debug.Print d
End Sub

文字列の部分を複数一気に取り出すことができる汎用関数としてなかなか使い勝手が良いのでシステム運用の業務で重宝している。

直接日付を取り出す関数じゃないので若干タイトル詐欺になってしまったけれど。。

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。