Mutable_Yunの業務改善ブログ

業務改善や生産性向上のブログです。自動化の手段として、VBAやRPAの勉強に役立つ解説をしています。

VBA フォルダの中をループで検索して、きょうの日付のファイルを開く

フォルダ内のファイルをループで検索する方法を使っていますか?
便利な方法なので、使い方と使いどころをマスターしましょう。

今回のレベルは中級です。
レベルについてはExcel VBAの実力(レベル)を定義してみる 初心者~三段をご参照ください。


目次

今回の概要

本当は「○○データ20190913.xlsx」の様に、固定の文字列に本日の日付を表す8桁のついたファイルを探して検索したいのですが、日々変わるファイル名が取得できず、仕方なくファイル名を「○○データ.csv」にしておいて、次の日にoldのフォルダに移すときに昨日の日付をファイル名に手入力している。

そんな状況を想定します。

確かに特定の日付や月の名前がファイル名の一部になったファイルを開きたいことは良くあります。

ユーザーに選択してもらう手も有りますが、本日の日付を選択すると決まっているのなら、完全自動化してしまいましょう。

これができれば、タスクスケジューラーである時刻にエクセルマクロブックを開くように設定し、そのエクセルにブックを開いたらマクロを自動で起動する様にすることで、パソコンにログインさえしておけば、勝手にマクロが起動するところから作業完了まで、人がパソコンを操作することなく作業を終えることができます。

これはもう、ちょっとした便利ツール以上のものでしょう。

Dir関数の挙動を復習する

Dir関数は他ブログなどでとても分かりやすい解説があるので詳細な文法はここでは割愛しますが、ざっくり言うと、引数にフルパスを渡し、フォルダ内にそのファイルが存在すれば、ファイル名、つまり、フルパスの一番右の\または円マークの右の文字から一番最後までを返します。


ポイントは引数をとらなければカレントディレクトリの適当なファイルのファイル名を返すことです。

Do~Loopステートメントの内側で引数なしで記述した場合、カレントディレクトリ内の中のファイルを、ランダムに、しかしダブりなく探してフルパスを返そうとします。返せないときは空の文字列””が返ります。

Do ~Loopステートメントでループを生成する

Sub フォルダ内で昨日の勤務実績データを探して開く()
'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
'このプロシジャは「勤務実績YYYYMMDD.xlsx」のファイルをフォルダから検索する
'YYYYMMDDは日付で、最新の勤務実績(大抵は昨日)のファイルを開きたいが、
'会社休日に対応するため、最近のファイルを開くことにしたい
'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    Const folder As String = "C:\Users\hogehoge\Desktop\勤務実績\" 'ここは実際のフォルダ名にする
    Dim 日付の8桁 As Long
    Dim 直近の日付 As Long '初期値は0が入る
    
    Dim temp_file As String '順にファイルをチェックしていくときに、
                                          'ファイル名(勤務実績YYYYMMDD.xlsxの部分)を一時的に格納する
                                          
    'ここから本番
    temp_file = Dir(folder & "勤務実績*")  '初期設定。
    
    Do While temp_file <> "" 'Dirが何も返さなくなるまで、つまりファイルを全てチェックし終わるまで繰り返す
        
        日付の8桁 = Mid(temp_file, 5, 8) 'ファイル名の5文字目から8文字目までがYYYYMMDD
        
        If 直近の日付 < 日付の8桁 Then  'このプロシジャの肝。日付を単に数字の大小で比較している
            直近の日付 = 日付の8桁
        End If
        
        temp_file = Dir() '引数をとらなければ次の未検索のファイルを探す。未検索のファイルがなくなると””を返す
    Loop
    
    'ループを抜けた時点で最新の日付が得られた
    Workbooks.Open Filename:=folder & "勤務実績" & 直近の日付 & ".xlsx"
    
End Sub

いかがでしょうか。フォルダの中を順に検索する事のメリットが見えたでしょうか。ファイル名が判明しているのが分かっている場合は必要ありませんが、今回のように、日付部分のみが変わる最新のファイルを探す、と言った場合に重宝します。

これにDateSerial関数を組み合わせると、毎月月末のファイルだけを順に開いて、今年度の累積勤務時間を求める、と言うようなことも考えられます。

DateSerial関数については別のところで触れたいと思います。

それでは、早速フォルダ内でDo~Loopを使ってファイル探索を実装してみて下さい。