VBAの操作中、実行しているファイルの名前を取得したり、ファイルやフォルダが存在するかどうかを確認したくなる時がありませんか?
今回の記事では、そうした悩みを抱えた時に役に立つ、ファイル名・フォルダ名の取得方法について解説していきたいと思います。
まずはファイル名を取得するための主な2つのパターンについて解説し、取得する際に使用するInStrRev関数、Dir関数についても合わせて紹介していきます。
VBAを実行しているファイルの名前を取得する方法を解説
まず初めに、1つ目のパターンである、VBAを実行しているファイルの名前を取得する方法を紹介します。
ファイル自身の名前については、以下のプロパティを使用することで、マクロを実行しているブックの名前を取得することができます。
ThisWorkbook.Name
試しに、こちらのプロパティを使って名前を表示してみたいと思います。
【サンプルコード】
Sub test()
MsgBox "マクロ実行中のファイル名:" & ThisWorkbook.Name
End Sub
【実行結果】
このように、ThisWorkbook.Nameを使うことで、実行中ファイルの名前を取得することができます。
また、似たプロパティにActiveWorkBookというものがあります。
それぞれの違いについては以下の通りです。
- ThisWorkBook:マクロ実行中のワークブック
- ActiveWorkBook:現在表示しているワークブック
次のサンプルコードで、動作の違いを実際に見てみましょう。
【サンプルコード】
Sub Test()
Workbooks.Open ThisWorkbook.Path & "\" & "Sample2.xlsm"
MsgBox "マクロ実行中のブック名:" & ThisWorkbook.Name & Chr(13) & "アクティブワークブック名:" & ActiveWorkbook.Name
End Sub
【実行結果】
マクロ実行中に新たにファイルを開いたことで、実行中のワークブックと表示中のワークブックが別となったことが分かると思います。
1つのみのファイルを操作する場合はどちらも同じ結果になりますが、このように複数のワークブックを処理する場合は2つの違いが重要になってくるので、合わせて覚えておくといいでしょう。
分かっているファイルパスからVBAでファイル名を取得する方法を解説
続いて2つ目のパターンである、ファイルパスからファイル名を取得する方法を紹介します。
ファイルパスから取得する方法はいくつかありますが、今回は以下の2つについて解説していきたいと思います。
- InStrRev関数を使って切り出す方法
- Dir関数を使う方法
それぞれの使い方について、詳しく見ていきましょう。
InStrRev関数でファイル名を切り出す方法を解説
まずは、InStrRev関数を使う方法について解説します。
この関数は、対象となる文字列の末尾から指定した文字列を検索し、最初に文字が見つかった位置を返してくれる関数です。使い方次第では、ファイル名だけでなくフォルダ名も取り出すことができます。
InStrRev関数の基本構文は以下の通りです。
InStrRev(stringcheck, stringmatch [,start [,compare]])
stringcheckには検索対象となる文字列を、stringmatchには検索したい文字列をそれぞれ入力します。
startでは、検索を開始したい文字位置を指定することができ、入力した数分を先頭から数えた位置を末尾として検索を行います。開始位置ついては省略が可能で、何も入れなかった場合は文字列末尾からの検索になります。
compareでは、文字列の比較方法を指定することができます。0を入れると、大文字小文字などを区別するバイナリ比較となり、1を入れると区別をしないテキスト比較になります。
こちらも開始位置と同様に省略可能で、指定しなかった場合のデフォルトはバイナリ比較です。
それでは実際に、以下のサンプルコードでファイル名を取得してみます。
【サンプルコード】
Sub sample()
Dim Path, FileName As String
Dim Pos As Long
Path = "C:\Users\Documents\sample.xlsx"
Pos = InStrRev(Path, "\")
FileName = Mid(Path, Pos + 1)
MsgBox FileName
End Sub
【実行結果】
初めに、「\」がある位置をパスの中から検索し、結果をPosに代入します。
次に、Mid関数という文字列を特定の位置から取り出してくれる関数を使って、ファイル名を取り出します。Posに代入されているのは「\」の位置なので、+1をすることでその隣の文字から抜き出すことができます。
Dir関数を使ってファイル名を取得する
続いて、Dir関数を使った方法について解説していきます。
Dir関数は、指定した条件に一致するファイルやディレクトリ、フォルダ名、またはドライブのボリュームラベルを文字列で返す関数です。
さっそく、詳しい使い方について見ていきましょう。
Dir関数の使い方は?
Dir関数を使う際は、以下のように書きます。
【基本構文】
Dir [(pathname [,attributes])]
pathnameには、検索対象のファイル、またはフォルダのパスを指定します。ワイルドカード ( * や ? ) を使用して、特定のパターンに一致するファイルを検索することもできます。
attributesには、検索するファイルの属性を指定することができます。pathnameとattributesのどちらも、省略することは可能です。
pathnameが見つからない場合は、長さ0の空文字(“”)が返されます。ファイルの有無に関わらず値が返されることになるので、Dir関数を使う場合には空文字が返却されるケースを想定して設計する必要があります。
実際にDir関数を使ってファイル名を取得してみよう
Dir関数を使用した際の動きを、以下のサンプルコードで確認してみましょう。
【サンプルコード】
Sub sampleTest1()
Dim Path As String
Path = "C:\Users\User\Desktop\Sample1.xlsm"
MsgBox Dir(Path)
End Sub
【実行結果】
このように、Dir関数を使用してファイル名を取得することができます。
ファイルが存在しているかどうかをDir関数でチェック
Dir関数で返された値とファイル名が一致するか判定することで、ファイルの存在をチェックすることもできます。
以下がそのサンプルコードです。
【サンプルコード】
Sub sampleTest2()
Dim Path, FileName As String
Path = "C:\Users\User\Desktop\Sample1.xlsm"
FileName = Dir(Path)
'Dir関数の戻り値がファイル名と一致するかチェック
If (FileName = "Sample1.xlsm") Then
MsgBox "Sample1.xlsmは存在します"
Else
MsgBox "Sample1.xlsmは存在しません"
End If
End Sub
【実行結果】
フォルダが存在しているかどうかをDir関数でチェック
‘ファイルのチェックはパス名のみで使用できますが、フォルダの存在をチェックする場合には、Dir関数のattributesで「vbDirectory」を指定する必要があります。その際、pathnameにはファイルでなく検索したいフォルダのパス名を指定します。
実際に確認してみましょう。
【サンプルコード】
Sub sampleTest3()
Dim Path, FolderName As String
Path = "C:\Users\User\Desktop"
FolderName = Dir(Path, vbDirectory)
If (FolderName = "Desktop") Then
MsgBox FolderName & "は存在します"
Else
MsgBox FolderName & "は存在しません"
End If
End Sub
【実行結果】
ファイルのチェック時と同じようにフォルダ内のファイルまでをパスに含めてしまうと、フォルダ名でなくファイル名が返却されてしまうので、フォルダ名を検索したい場合はパスの指定の仕方に注意しましょう。
ファイルの一覧を取得する方法は?
先ほども少し説明したように、Dir関数ではpathnameにワイルドカードを使用することで、指定したパターンに一致するファイル名を検索することができます。
例えば、次のサンプルコードのように拡張子を指定して、取得したいファイルの一覧を表示することも可能です。
Sub sampleTest4()
Dim Path, FileName, Msg As String
'「*」ワイルドカードを使用
Path = "C:\Users\User\Desktop\*.xlsm"
FileName = Dir(Path)
'ファイル名が見つからなくなるまでループ
Do While FileName <> ""
Msg = Msg & FileName & vbCrLf
'次のファイル名を取得
FileName = Dir()
Loop
MsgBox Msg
End Sub
【実行結果】
このサンプルコードでは、ワイルドカードを使用して拡張子が「.xlsm」と一致するファイル名を取得しています。
一度Dir関数を使用した後、ループ内で引数を指定せずに再びDir関数を使用することで、同じ指定条件に一致する別のファイルを取得してくれるので、これを繰り返すことで一覧を表示することができます。
取得した際の一覧の表示順は、ファイル名の昇順になっています。順番を入れ替える機能はDir関数にはないので、ソートしたい場合は他の方法を使用する必要があります。
フォルダ内のサブフォルダを取得する方法を解説
次に、フォルダの一覧を取得する方法を解説していきます。
基本的な方法はファイルの一覧表示と同じように、ループで処理をしてフォルダ名を取得していきます。pathnameに検索したいフォルダ内をパスを、attributesには「vbDirectory」を指定します。
【サンプルコード】
Sub sampleTest5()
Dim Path, FileName, Msg As String
Path = "C:\Users\User\Desktop\"
FileName = Dir(Path, vbDirectory)
Do While FileName <> ""
'ファイル・フォルダの属性を判定してフォルダだけ処理
If GetAttr(Path & FileName) And vbDirectory Then
'「.」「..」の除外
If FileName <> "." And FileName <> ".." Then
Msg = Msg & FileName & vbCrLf
End If
End If
FileName = Dir() '引数なしで次のファイル名を取得
Loop
MsgBox Msg
End Sub
【実行結果】
Dir関数で取得する段階では、フォルダ名だけでなくファイル名も対象に含まれてしまうので、サンプルコードではGetAttrというファイルやフォルダの属性を判定できる関数を使用して、フォルダの時のみ表示処理をしています。
また、カレントフォルダを表す「.」と、その親フォルダを表す「..」も結果に含まれるため、こちらも条件分けをして除外しています。
エラーが発生した場合はどうする?注意点を解説
Dir関数を使う際に、エラーが発生するケースがいくつか存在します。
それぞれの原因についてと、その対処法を以下で解説していきたいと思います。
【pathnameの指定に関するエラー】
pathnameは状況により省略することも可能ですが、タイミング次第ではエラーが発生する場合があります。
・最初に呼び出すとき
一番最初に呼び出すDir関数においては、pathnameは必ず指定する必要がありますので注意しましょう。
一度呼び出した後であれば、省略しても先に呼び出した関数と同じ条件で検索をしてくれます。
・戻り値に長さ0の空文字が返された後
Dir関数は、pathnameで指定されたファイルやサブフォルダが見つからない場合は長さ0の空文字を返します。戻り値で空文字を返された場合、再度pathnameを指定する必要がありますので、関数を使う際には空文字が返されるケースを想定して設計するよう注意しましょう。
【検索対象のパス名が長すぎた場合】
こちらはWindows環境によるもので、Dir関数では256バイトを超えるパス名を扱うことができません。
対象のパス名が256バイトを超えている場合には、FileSystemObjectを使用する方法があります。
FileSystemObjectオブジェクトのFolderExistsメソッドなどを利用して、ファイルやフォルダの存在をチェックすることができます。
【3文字の拡張子を指定した場合】
こちらは厳密にはエラーではありませんが、Dir関数を使用する上で発生しやすい問題点のため、注意が必要です。
例えば、指定のフォルダ内に次の3つのファイルがあったとします。
- Book1.xls
- Book2.xlsx
- Book3.xlsm
この際、ワイルドカードを使って「*.xls」と指定し一覧を取得しようとすると、xlsファイルだけでなくxlsxファイルとxlsmファイルも一覧の中に含まれてしまいます。
これもWindows環境によるもので、Dir関数で3文字の拡張子を指定した場合、その3文字「で始まる」拡張子が該当すると判断されます。上のような「.xls」のケースの他にも、HTMLファイルで使われる「.htm」と「.html」も同じように扱われます。
もし、拡張子が「.xls」のファイルだけを一覧で取得したい場合などには、以下のサンプルコードのようにすると、必要なファイル名だけを表示することができます。
【サンプルコード】
Sub sampleTest6()
Dim Path, FileName, Msg As String
'「*」ワイルドカードを使用
Path = "C:\Users\User\Desktop\*.xls"
FileName = Dir(Path)
'ファイル名が見つからなくなるまでループ
Do While FileName <> ""
If LCase(FileName) Like "*.xls" Then
Msg = Msg & FileName & vbCrLf
End If
'次のファイル名を取得
FileName = Dir()
Loop
MsgBox Msg
End Sub
また、FileSystemObjectを使用した場合には、拡張子を返すGetExtensionNameメソッドを利用することもできます。状況に応じて使い分けるといいでしょう。
まとめ
ここまで、ファイル名を取得する様々な方法について解説してきましたが、いかがでしたでしょうか?
いずれも、VBAを扱う上で様々な処理に応用することができる方法なので、覚えておいて損はないでしょう。
ぜひこの記事を参考に、活用してみてください!
関連記事
VBAの勉強方法は?
書籍やインターネットで学習する方法があります。昨今では、YouTubeなどの動画サイトやエンジニアのコミュニティサイトなども充実していて多くの情報が手に入ります。
そして、より効率的に知識・スキルを習得するには、知識をつけながら実際に手を動かしてみるなど、インプットとアウトプットを繰り返していくことが重要です。特に独学の場合は、有識者に質問ができたりフィードバックをもらえるような環境があると、理解度が深まるでしょう。
ただ、VBAに限らず、ITスキルを身につける際、どうしても課題にぶつかってしまうことはありますよね。特に独学だと、わからない部分をプロに質問できる機会を確保しにくく、モチベーションが続きにくいという側面があります。独学でモチベーションを維持する自信がない人にはプログラミングスクールという手もあります。費用は掛かりますが、その分スキルを身につけやすいです。しっかりと知識・スキルを習得して実践に活かしたいという人はプログラミングスクールがおすすめです。
プログラミングスクールならテックマニアがおすすめ!
ITスキル需要の高まりとともにプログラミングスクールも増えました。しかし、どのスクールに通うべきか迷ってしまう人もいるでしょう。そんな方にはテックマニアをおすすめします!これまで多くのITエンジニアを育成・輩出してきたテックマニアでもプログラミングスクールを開講しています。
<テックマニアの特徴>
・たしかな育成実績と親身な教育 ~セカンドキャリアを全力支援~
・講師が現役エンジニア ~“本当”の開発ノウハウを直に学べる~
・専属講師が学習を徹底サポート ~「わからない」を徹底解決~
・実務ベースでスキルを習得 ~実践的な凝縮カリキュラム~
このような特徴を持つテックマニアはITエンジニアのスタートラインとして最適です。
話を聞きたい・詳しく知りたいという方はこちらからお気軽にお問い合わせください。