VBAを実行している自分自身のファイル名の取得ってできないの?
ファイルやフォルダの存在や一覧を取得するにはどしたらいい?
VBAでファイル操作をしていると、上のような悩みを抱えることがあるのではないでしょうか?ファイル名やフォルダ名の取得は、方法を知らないと意外と悩んでしまうポイントですよね。
この記事では、ファイル名・フォルダ名の取得方法について網羅的に解説していきます。ファイル名の取得には大きく2パターンがあります。実行ファイル自身の名前を取得する方法と、ファイルパスから名前を取得する方法です。
さらに、そのなかでInStrRev関数、Dir関数、FileSystemObjectを使う方法を紹介していきます。
この記事を読めばファイル名・フォルダ名の取得は完璧といえるレベルまで理解できますので、しっかりと学習していきましょう。
VBAで自分のファイル名を取得する方法
まずは、VBAを実行しているファイル自身の名前を取得する方法を紹介します。
自身の名前に関しては、以下で紹介するように関数を使うのではなく、専用のプロパティが用意されているので、そちらを利用します。ThisWorkBook.Nameというプロパティです。
名前を表示する際の書式
ThisWorkbook.Name
サンプル
Sub test() MsgBox "マクロを実行しているブックは" & ThisWorkbook.Name End Sub
実行結果
このように、ThisWorkbook.Nameを使うことでマクロを実行しているブックの名前を表示することができます。
似たような使い方ができるプロパティにActiveWorkBookがありますが、違いは以下の通りです。
- ThisWorkBook:マクロを実行しているワークブック
- ActiveWorkBook:現在表示しているワークブック
主に複数のワークブックにまたがるような処理を書いた場合、この違いが重要になってきます。そのような場面になったら思い出してください。
こちらでも詳しく紹介していますので、興味のある方は是非どうぞ。
ActiveSheet.Nameというプロパティを使えば似たような方法でシート名も取得できます。こちらも詳しく説明した記事がありますので、ぜひご覧ください。
VBAでファイルパスからファイル名を取得する方法3選!
つづいて、より一般的なファイル名を取得する方法を紹介します。これから紹介する方法はすべて共通してファイルのパスがわかっている必要があります。
ファイルのパスとは、ファイルの所在を示す住所のようなものです。たとえば、Cドライブの直下にSamuraiという名前のフォルダがあり、その中にsamurai.txtというテキストファイルがあったとすると、そのパスはC:Samuraisamurai.txtとなります。
なお、(バックスラッシュ)はWindows上では半角の¥マークで表示されます。コンピュータを扱う上での約束事なので覚えておいてください。
さて、ファイル名・フォルダ名を取得する方法に話を戻します。ファイルのパスから名前を取得する方法は次の3パターンがあります。
- InStrRev関数で切り出す方法
- Dir関数を使う方法
- FileSystemObjectを使う方法
それぞれ固有のメリットがあるので、ひとつずつ見ていきましょう。
InStrRev関数でファイル名を切り出そう
まず紹介するのはInStrRev関数を使う方法です。シンプルな方法なので応用できる範囲が広いです。また、標準の関数のみを使っているため、Excelのバージョンの影響を受けにくい、というのもメリットですね。
それでは方法を解説していきます。まずはメインとなるInStrRev関数の解説から。この関数は指定した文字列を終端から対象となる文字を検索します。
InStrRev関数の書式
InStrRev(検索対象の文字列,検索する文字列[,開始位置[,検索モード]])
第1引数、第2引数はそれぞれ対象となる文字列、検索したい文字列が入ります。
第3引数は文字列先頭から数えた数で、ここに入力した文字数から先頭に向かう検索を行います。例えば、開始位置が6の場合、6文字目から先頭に向かって検索していきます。省略した場合と-1を入力した場合文字列末尾からの検索になります。第3引数以下は省略可能です。
第4引数も省略可能で、0を入れると大文字小文字などを区別するバイナリ比較、1を入れると大文字小文字などを区別しないテキスト比較が可能です。デフォルトはバイナリ比較で、テキスト比較を行う場合、第3引数の開始位置の指定が必須になります。
テキスト比較で同一とされるものは以下のものです。
- 大文字と小文字
- 半角文字と全角文字
- ひらがなとカタカナ
では、実際にInStrRev関数を使ってファイル名を取得してみましょう。今回はC:Samuraisamurai.txtからファイル名を取得してみます。
サンプル
Sub InStrRevSample() Dim FilePath As String, FileName As String, Pos As Long FilePath = "C:Samuraisamurai.txt" Pos = InStrRev(FilePath, "") FileName = Mid(FilePath, Pos + 1) MsgBox FileName End Sub
このサンプルでは、パスのがある位置を後ろから検索し、Posに記録します。その後、文字列を特定の位置から書き出すMid関数を使って、パスからファイル名だけを取り出しました。Posが+1されているのはを含めないための調整です。
この方法を使えば、パス次第でファイル名もフォルダ名も取り出すことができますね。
なお、InStrRev関数はNullが検索対象の文字列に代入されるとNullを返します。そのため、パスが存在するかわからないときはこちらのほうがオススメです。
Dir関数を使ってファイル名を取得しよう
つづいて、Dir関数を使った方法を見ていきましょう。こちらも標準関数によるバージョン安定性があり、専用の関数を使っているためにできることの種類が多くなっています。
VBAのDir関数とは
Dir関数とは、ファイル名やフォルダ名を取得する場合に使用します。
以下のように記述します。
Dir[(pathname[, attributes])]
引数の指定方法は以下のとおりです。
- 引数pathnameには絶対パス名を指定します。
- 引数「attributes」は省略することができます。
- 引数を省略すると、続けて次のファイル名を取得することができます。
Dir関数の戻り値には引数pathnameで指定したファイル、フォルダの名前、またはドライブのボリュームラベルを表す文字列を返します。
pathnameが見つからない場合は、長さ0の空文字(“”)が戻り値になります。この特性のため、ファイルが存在しようとしまいと値を返すので、うまく設計しないと空文字の処理に手間取ることがあります。
pathnameにはワイルドカードを利用することができます。
引数attributesの設定値については表にまとめました。
定数 | 値 | 説明 |
---|---|---|
vbNormal | 0 | 属性のないファイル (デフォルト値) |
vbReadOnly | 1 | 属性のないファイルと 読み取り専用のファイル |
vbHidden | 2 | 属性のないファイルと 隠しファイル |
vbSystem | 4 | 属性のないファイルと システムファイル Macでは使用不可 |
vbVolume | 8 | ボリュームラベル Macでは使用不可 |
vbDirectory | 16 | 属性のないファイルと フォルダ |
vbAlias | 64 | ファイル名がエイリアスとして 設定されているファイル Macでのみ使用可能 |
Dir関数でファイル名を取得
Dir関数はpathnameで指定したファイルパスのファイル名を返すことができます。
サンプルコードで確認しましょう。
Sub macro0() Dim str1 As String, str2 As String str1 = "C:Program Files (x86)Microsoft OfficerootOffice16EXCEL.EXE" MsgBox Dir(str1) End Sub
実行結果:
このサンプルコードでは、まずDir関数の第1引数にファイルの絶対パスを指定しています。そして、Dir関数の実行結果をメッセージに表示しました。
Dir関数でファイルの存在をチェック
Dir関数はpathnameで指定したファイル名を返すので、戻り値がファイル名と一致するか判定することでファイルの存在をチェックすることができます。
サンプルコードで確認しましょう。
Sub macro1() Dim str1 As String, str2 As String str1 = "C:Program Files (x86)Microsoft OfficerootOffice16EXCEL.EXE" str2 = Dir(str1) If (str2 = "EXCEL.EXE") Then MsgBox "EXCEL.EXEが見つかりました" Else MsgBox "EXCEL.EXEは見つかりませんでした" End If End Sub
実行結果:
このサンプルコードでは、まずDir関数の第1引数にファイルの絶対パスを指定しています。そしてファイルが存在するかチェックするために、Dir関数の戻り値がファイル名と一致するか判定しました。
Dir関数でフォルダの存在をチェック
フォルダの存在をチェックするには、Dir関数の第2引数をvbDirectoryで指定します。第1引数はそのフォルダを含む親フォルダのパス名やドライブ名を指定します。
サンプルコードで確認しましょう。
Sub macro2() Dim str1 As String, str2 As String str1 = "C:Program Files (x86)Microsoft OfficerootOffice16" str2 = Dir(str1, vbDirectory) If (str2 = "Office16") Then MsgBox "Office16が見つかりました" Else MsgBox "Office16は見つかりませんでした" End If End Sub
実行結果:
このサンプルコードでは、まずDir関数の第1引数にフォルダの絶対パスを指定しています。そして第2引数にはvbDirectoryを指定し、対象をフォルダで指定しています。
フォルダが存在するかチェックするために、Dir関数の戻り値がフォルダ名と一致するかを判定しました。
ワイルドカードでファイル一覧を取得
Dir関数では第1引数にワイルドカードを利用することができます。ワイルドカードを指定することで、指定したパターンにマッチするファイル名を複数取得することができます。
ワイルドカードに使える文字を下の表にまとめました。
文字 | 説明 |
---|---|
? | 任意の1文字 |
* | 0文字以上の文字 |
# | 0~9の半角数字 |
[charlist] | charlistに含まれる全角または半角の1文字 |
[!charlist] | charlistに含まれない全角または半角の1文字 |
例えば、拡張子が同じファイルを複数取得することも可能です。
サンプルコードで確認しましょう。
Sub macro3() Dim str1 As String, str2 As String, msg As String str1 = "C:Program Files (x86)Microsoft OfficerootOffice16*.EXE" '「*」ワイルドカードを使用 str2 = Dir(str1) Do While str2 <> "" 'ファイル名が見つからなくなるまでループ msg = msg & str2 & vbCrLf str2 = Dir() '引数なしで次のファイル名を取得 Loop MsgBox msg End Sub
実行結果:
このサンプルコードでは、Dir関数の引数にString型変数str1を指定しています。str1にはワイルドカードを使用した文字列が格納されていますので、そのパターンにマッチするファイル名を取得しています。
この場合は拡張子が”EXE”と一致するファイル名を取得していますね。
パターンにマッチするファイル名が複数存在する可能性がありますので、Dir関数の引数を指定せずに次のファイル名を取得するようにしています。
ちなみに、ファイル名の一覧の表示順はファイル名の昇順になっています。この順番をソートして入れ替える機能はDir関数にはありません。
順番をソートしたい場合は、Excelシート上のソートを使う方法がオススメです。シート上のソートはVBAからでもSortメソッド、Sortオブジェクトを使って操作できます。
VBAでのソートの操作についてはこちらのサイトで詳しく解説していますので、ぜひ参考にしてください。
また、ワイルドカードの使い方については、こちらのサイトで詳しく解説しています。
ぜひ参考にしてください。
サブフォルダ、ファイル一覧を取得
Dir関数の第2引数にvbDirectoryを指定すると、ファイルとフォルダの名前を取得することができます。
これを利用してサブフォルダ名とファイル名のリストを取得してみましょう。
サンプルコードは次のとおりです。
Sub macro4() Dim str1 As String, str2 As String, msg As String str1 = "C:Program Files (x86)Microsoft Office*" '「*」ワイルドカードを使用 str2 = Dir(str1, vbDirectory) Do While str2 <> "" 'ファイル名、フォルダ名が見つからなくなるまでループ If InStr(str2, ".") <> 1 Then '「.」「..」の除外 msg = msg & str2 & vbCrLf End If str2 = Dir() '引数なしで次のファイル名、フォルダ名を取得 Loop MsgBox msg End Sub
実行結果:
このサンプルコードでは、Dir関数の第1引数にString型変数str1を指定しています。また、第2引数にはvbDirectoryを指定していますので、ファイル名もしくはフォルダ名を返します。
str1にはワイルドカードを使用した文字列が格納されていますので、そのパターンにマッチするファイル名、フォルダ名を取得しました。
パターンにマッチするファイル名、フォルダ名が複数存在する可能性がありますので、Dir関数の引数を指定せずに次のファイル名、フォルダ名を取得するようにしています。
この場合も、ファイル名、サブフォルダ名の一覧の表示順はファイル名の昇順になっています。先ほどお伝えしましたように順番をソートして入れ替える機能はDir関数にはありません。
SortメソッドやSortオブジェクトを使ってソートするようにしましょう。
なお、InStr関数を使ってファイル名、フォルダ名の1文字目に”.”(ピリオド)が含まれる場合は結果表示から除外しています。
これは「.」がカレントフォルダ、「..」がカレントフォルダの親フォルダを示し、これもフォルダとしてDir関数の戻り値に含まれるからです。Windowsの場合ファイルエクスプローラでは「.」「..」は表示されませんので、結果表示からも削除しています。
InStr関数の使い方については、こちらのサイトで詳しく解説していますので、ぜひ参考にしてください。
エラーが発生する場合の注意点
Dir関数を使っていて、エラーが発生する場合があります。原因はいくつかありますので、以下にご紹介します。
引数pathnameの指定でのエラー
ファイル名やサブフォルダ名の一覧を取得する場合にDir関数の引数を省略するとお伝えしました。これに関してエラーが発生する場合があります。
最初に呼び出すとき
Dir関数を最初に呼び出す場合は、引数pathnameは必ず指定する必要がありますので注意しましょう!
戻り値に長さ0の文字列が返された後
Dir関数は引数pathnameで指定されたファイル、サブフォルダが見つからない場合は戻り値に長さ0(ゼロ)の空文字を返します。戻り値が一度ゼロ(0)の文字列を返した場合は、再度引数pathnameを指定する必要がありますので注意しましょう。
Windows環境での注意点
拡張子xlsでの注意点
これはエラーではありませんが、Excelの拡張子はxlsやxlsx、xlsmと複数あります。この場合、ワイルドカードを使って”*.xls”と指定しても、一覧にはxlsx、xlsmファイルも一覧の中に含まれます。
Sub macro5() Dim str1 As String, str2 As String, msg As String str1 = "C:UsersDir*.xls" '「*」ワイルドカードを使用 str2 = Dir(str1) Do While str2 <> "" 'ファイル名が見つからなくなるまでループ msg = msg & str2 & vbCrLf str2 = Dir() '引数なしで次のファイル名を取得 Loop MsgBox msg End Sub
実行結果:
これはDir関数での不具合というよりも、Windows環境によるものです。もし、拡張子が”xls”のファイルだけ一覧で取得したい場合は以下のサンプルコードのようにすると大丈夫です。
Sub macro6() Dim str1 As String, str2 As String, msg As String str1 = "C:Usershiro2OneDriveDir*.xls" '「*」ワイルドカードを使用 str2 = Dir(str1) Do While str2 <> "" 'ファイル名が見つからなくなるまでループ If LCase(str2) Like "*.xls" Then msg = msg & str2 & vbCrLf End If str2 = Dir() '引数なしで次のファイル名を取得 Loop MsgBox msg End Sub
実行結果:
このサンプルコードでは、Like演算子とワイルドカードを使って、ワイルドカードにマッチするファイル名だけを一覧に表示するようにしています。
長すぎるパス名
これもWindows環境によるものです。Windows環境では256バイトを超えるパス名は扱えません。
ネットワークドライブなどのパスで256バイトを超えている場合は、FileSystemObjectで扱う方法があります。FileSystemObjectオブジェクトのFolderExistsメソッドなどでフォルダの存在をチェックすることができます。
FileSystemObjectオブジェクト、FolderExistsメソッドの詳しい使い方については、こちらでくわしく解説しました。
ぜひ参考にしてください。
FileSystemObjectを使う方法
ここではこれまでと異なり、外部オブジェクトのFileSystemObjectを使う方法を紹介します。
FileSystemObjectってなんだ?という方はこちらに基礎的な内容がまとめてありますので、是非ご覧になってからこの章を読み進めてください。
この章ではMicrosoft Scripting Runtimeの参照設定が完了しており、FileSystemObjectが使える前提で進めていきます。
FileSystemObjectを使う場合、ファイル名・フォルダ名の取得は単純です。GetFileNameメソッドでファイル名・フォルダ名を取得するだけです。
サンプル
Sub FSOSample() Dim fso As New FileSystemObject, FileName As String FileName = fso.GetFileName("C:Samuraisamurai.txt") MsgBox (FileName) End Sub
非常にシンプルに記述できましたね!
なお、GetFileNameメソッドはパスが存在しない場合、空文字("")を返します。パスの存在確認も行われないので、パスが存在しない可能性がある場合は、FileExistsなどのメソッドを使った条件分けが必要になります。
FileSystemObjectはGetFileName以外にも拡張子を含まないファイル名を返すGetBaseNameメソッドやファイルの拡張子を返すGetExtensionNameメソッドがあるので、上手に活用したいですね。
FileSystemObjectは導入に若干の手間があるのと、Excelバージョン間で不具合の原因になりうる可能性をふくみます。ですが、記述そのものは非常に簡単で、様々なことが実現できる方法です。
まとめ
いかがでしたか?今回はVBAを使ってファイル名を取得する方法を3パターン、自身の名前を取得する方法で1個見てきました。
実現できる方法は何種類かありますので、適切な方法を選択できるように知識を深めていただけたらと思います。
ぜひ、ファイル操作を使いこなしVBAのレベルをあげていきましょう!