Dir関数でフォルダ内の複数ファイルを順番に処理
皆様はマクロを書いたワークブックから別のワークブックに対して作業をしたいと思った事はありませんか?
具体的には以下のような作業になります。
- A.xlsmからB.xlsxのファイル名を取得したい
- A.xlsmからC.xlsxのデータを開きたい
- A.xlsmから〇〇フォルダ内にある複数の.xlsxファイルを順番に開いて作業したい
特に一番下の作業は難しそうですね。しかしある関数を使う事で3つ全ての作業ができる様になります。
Dir関数です。Dir関数は他の機能(繰り返し処理など)と合わせて使うと色々な事ができます。
複数の.xlsxファイルを扱えるとワークブック間の転記やコピー&ペーストも可能になりますよ。
「フォルダ内のファイルを順番に処理」するという作業はよく質問をいただく作業の中の1つです。
皆様課題として悩まれている様です。そこで課題を解決させる為にDir関数を使った回答用の記事を用意しました。
以下3つのポイントをもとにDir関数について解説します。
- 基礎編:Dir関数の基本的な使い方
- 基礎編:Dir関数の引数について
- 応用編:フォルダ内の複数ファイルを順番に処理する方法
プロシージャ内のコードが実行されながらファイルが選択される様を見る事ができますよ。
関連記事
コード内で「Set」を使うオブジェクト変数についてはこちらの記事で詳しく解説しています。
オブジェクト変数VBAで転記|ブック間で文字列をコピペするマクロの作り方を教えます
「ThisWorkbook.Path」の使い方はこちらの記事で詳しく解説しています。
パスの書き方【VBA】絶対パス相対パスの書き方|理解はカレントディレクトリがポイント
この本で勉強しました
この書籍はテクニック集です。実務で役に立つコードが沢山書いてありとても便利なんですよ。
私はこの書籍を会社の机の上に置いています。
何かあったら本を開いてヒントをもらうという使い方をしています。
Dir関数についても事例やコードが用意されていますので紹介させていただきました。
電子書籍(Kindleストア)はこちらです。私一部の書籍は電子書籍で購入しています。
電子書籍をVBEと同じ画面で横に並べながら作業する事で作業効率が劇的にあがります。
Dir関数は文字列を返す関数
まずはDir関数について説明します。Microsoftのリファレンスから定義を引用します。
指定したパターンまたはファイル属性に一致するファイル、ディレクトリ、フォルダーの名前、またはドライブのボリューム ラベルを表す String を返します。
Wikipedia:Dir関数
「Stringを返す」と書いてあるので戻り値は文字列です。具体的な使い方は以降で解説します。
構文と引数の種類
構文と引数について紹介します。
一般的に関数の引数というのは第1引数がマストで第2引数以降が任意というかたちが多いです。
しかしこの関数は全ての引数が任意です。コの字かっこ(ブラケット)が大外に配置されていますね。
という事は Dir() というかたち(引数無)で使う事があるという事です。詳細は応用編で解説します。
まずは引数の勉強をしましょう。それぞれの引数については以下テーブルをご覧ください。
番号 | 引数 | 説明 |
---|---|---|
1 | pathname | 省略可能。ファイル名を指定する文字列式です。 ディレクトリまたはフォルダー、およびドライブを含めることができます。 pathname が見つからない場合は、長さ 0 の文字列 (“”) が返されます。 |
2 | attributes | 省略可能。 ファイル属性を指定する定数または数式 (合計によって指定) です。 省略した場合は、pathname に一致する、属性のないファイルが返されます。 引数は複数形です。よって複数の属性を指定する事ができます。 |
attributesによって設定される属性は以下種類があります。
番号 | 定数 | 値 | 説明 |
---|---|---|---|
1 | vbNormal | 0 | 規定値です。属性のないファイルになります。 |
2 | vbReadOnly | 1 | 属性の無いファイル+読み取り専用ファイルです。 |
3 | vbHidden | 2 | 属性の無いファイル+隠しファイルです。 |
4 | vbSystem | 4 | 属性の無いファイル+システムファイルです。Mac使用不可。 |
5 | vbVolume | 8 | ボリュームラベルです。Mac使用不可。 |
6 | vbDirectory | 16 | 属性の無いファイル+ディレクトリ(フォルダ)です。 |
7 | vbAlias | 64 | エイリアス。(Macのみ使用可) |
基礎編:基本的な使い方
画像のような環境を用意しました。
続いて画像の中ではDir関数+引数にワイルドカードを使ったコードを紹介しています。
Sub Dir関数の使い方_基本編()
Dim pth As String
Dim file As String
pth = ThisWorkbook.Path & "\〇〇フォルダ\"
file = Dir(pth & "*.xlsx*")
Workbooks.Open (pth & file)
End Sub
\マークの記号はスラッシュorバックスラッシュでも使えます。
使用時は可読性を考慮して1つのプロシージャ内では統一させて使う様にしましょう。
コード内ではpthとfileという変数を宣言してから使っています。共にString型の変数です。
Dir関数の引数でpathnameとして変数pthと変数fileを使います。
結論としては変数fileには「B.xlsx」という文字列が格納されることになります。
最終的に変数pthとfileを使ってB.xlsxを開きます。(ThisWorkbook.Pathはこちらの記事で説明しています)
引数の中はどうなっているのか
Dir関数のかっこの中の話になります。
かっこの中に用意された引数は最終的には以下の様になります。2つの注意点を考慮して読んでください。
- Usersのあとの×××××は個人のアカウントが入ります。
- バックスラッシュが使えないので\を使っています。
「指定されたファイルパスにあるフォルダ内から拡張子が.xlsxのデータ名を1つ返して」という命令です。
ファイル名を *.xl* にしておけば.xls、.xlsx、.xlsmの複数拡張子を拾う事ができます。
この様にワイルドカードをうまく使えば複数拡張子のファイルであっても存在チェックが可能となります。
ワイルドカードの使い方についてはこちらの記事をご覧ください。
ワイルドカード完全解説VBAで文字列を比較Like演算子とワイルドカードで完全/部分一致を確認【一覧で表示】
戻り値について
*.xlsxのデータは一つしかありません。よって戻り値は「B.xlsx」になります。
ここで.xlsxのデータが複数存在した時はその中のうち1つの.xlsxが指定され文字列が返されます。
パスは返ってきません。ファイル名の文字列だけが変数fileに格納されます。
その他
第2引数のattributesは複数指定が可能です。「vbReadOnly+vbHidden」の様に書きましょう。
これで「属性の無いファイル+読み取り専用ファイル+隠しファイル」という様に複数条件を指定できます。
応用編:フォルダ内の複数ファイルを順番に処理する方法
基本編で関数の建付けと理屈を紹介しました。
応用編では実際に使う時にどうやってコードを用意するのかを紹介します。事例を用意しました。
この事例をもとに冒頭で紹介しました「フォルダ内の複数ファイルを順番に処理する方法」を解説していきます。
該当のプロシージャを実行する様を動画に撮っています。この後紹介します。
Sub Dir関数の使い方_応用編()
Dim pth As String
Dim file As String
Dim wb As Workbook
pth = ThisWorkbook.Path & "\〇〇フォルダ\"
file = Dir(pth & "*.xlsx*")
Do While Len(file) > 0
Set wb = Workbooks.Open(pth & file)
Workbooks(wb.Name).Close
Set wb = Nothing
file = Dir()
Loop
End Sub
\マークの記号はスラッシュorバックスラッシュでも使えます。
使用時は可読性を考慮して1つのプロシージャ内では統一させて使う様にしましょう。
動画:Dir関数で複数ファイルを操作する
コードを紹介しただけでは分かりにくいので動画を作成しました。
A.xlsmから〇〇フォルダ内の複数ファイルを順番に開く/閉じるというコードを紹介します。
今回は「できるだけ簡単に複数ファイルを順番に処理する」事だけに特化して説明します。
先にポイントを紹介しておきます。ポイントは2つです。
- Dir() ・・・ 引数無しのDir関数
- Do While ~Loop ステートメント
順番に説明します。読んでいただくと以降の動画が理解しやすいです。
Dir()
結論から先に申し上げますと2回目のDir関数のかっこ内の引数は無しで使います。理由は以下の通りです。
Dir関数は引数を無しにすると最初のDir関数で指定した条件で別のファイルをつかんでくれます。
新たにDir関数を用意して引数pathnameを設定するまで同じ条件でデータを捕まえてくれます。
Dir関数は返す文字列が無い時は””を返す
指定したpathnameに対象のファイルがある時はファイル名を返しますがない時は””を返します。
「返すファイルが無い」ので””(ダブルクォーテーション2つ)を返すという事になります。
Do While ~Loop ステートメント
Doを使ったステートメントは何種類かあるのですが今回はDo While ~Loopステートメントを使用します。
間単に説明すると「条件の結論がTrueの間はループを続けるよ」というステートメントです。
Len関数を使って条件を設定
今回はLen関数で変数fileの文字列を数えた結果文字数によって条件を分けるというコードを組んでいます。
具体的に申し上げますと「変数fileの文字列はゼロ以上ですか?」という条件を設定しています。
変数fileに文字列が設定されている間はループが回るという建付けです。Len関数についての記事はこちらです。
Len関数について解説VBAで文字列を取り出す複数のかっこの中の値を1クリックで集める
参考:For Each ~ Nextステートメント
こちらもDo While ~ Loop同様に繰り返し処理の記事です。
ブック内を周回し特定文字を含んでいるワークシートを選択するという作業を具体例を使って説明しています。
繰り返し処理マクロで特定文字を含むシートを選択|For Each ~ Next & Like
動画で作業の流れを確認
具体的に何が起こっているのかをチェックする為に動画を用意しました。(約4分半です)
Dir関数とDo While ~ Loopステートメントに注目して動画をみてください。
参考:Do While ~ Loopステートメントの終了は先頭で判断する
ループを抜けるかどうかは先頭の「Do While 条件」が判断しています。
「Do While 条件」でFalse判定がなされるとループを抜けます。
ループを抜けたら即End Subというわけではない
「なんでループを抜けたらすぐにEnd Subまで進むの?」と思った方は今一度コードを見直してください。
今回はLoopの後にコードが無いので最後のEnd Subまでコードが進んだだけです。あくまで配置の問題です。
参考:FileSystemObject(FSO)を併用する
FileSystemObject(FSO)を併用する事で複数フォルダ群を周回する事も可能です。
FileSystemObjectとは
かんたんに言うと「VBAでファイルやフォルダーを操作するための便利なオブジェクト」です。
具体的な使用方法を説明します。まずはVBEの参照設定で「Microsoft Scripting Runtime」を選択しましょう。
これでコード内でFilesystemObjectを使えるようになります。
できることをもう少し具体的に書き出してみます。
- ファイルやフォルダーの操作:ファイルやフォルダーの作成、削除、コピー、移動等ができます。
- ファイルやフォルダーの情報取得:ファイルやフォルダーのプロパティ(サイズ、作成日時等)を取得できます。
- ファイルの読み書き:テキストファイルの読み書きを行うことができます。
実際のコーディングに使う要素はMicrosoftのドキュメントをご覧ください。(FileSystemObject オブジェクト)
参考:FileSystemObjectを実際に使ってみました
こちらの記事には使用例が紹介されています。
できる事や機能としてある程度理解できたとしても事例に落とし込めないと意味がありません。
一番良いのはご自身の仕事で使ってみることですがいきなりは難しいので事例を読んでさらに理解を進めてください。
FSOを使ったコードVBAで画像を取り込む高速で画像自体を取得しエクセルに貼り付ける
FSO&サブルーチンVBAはフォルダ内の複数ブック×全部のシート名をセットで取得できる
FSO&再帰呼び出し&サブルーチン【VBA_再帰】複数フォルダ内を検索拡張子を決めて画像を取り出す
まとめ
Dir関数の基本的な使い方から応用までを見ていただきました。
応用編では複数ファイルを順番に操作する様を動画で紹介しました。イメージはつかめたでしょうか。
コードはとてもシンプルなのでフォーマットとしても使えるコードになっています。
実際に自分のVBEにコードを用意しフォルダやファイルなどの環境を用意してコードを動かしてみてください。
動画の中ではワークブックを開いてすぐ閉じてましたがコピペ等の作業をして保存してから閉じる事も可能です。
そうする事でマクロを書いた.xlsmから別ブックを操作する事ができる様になります。
PasteSpecialメソッドVBA×コピペ|値のみ貼り付け&簡単高速にコピーできる方法を公開
複数のワークブックを扱う際はオブジェクト変数の理解が進むと容易に操作出来る様になります。
冒頭でも紹介したこちらの記事を見ていただくと理解が進みます。
オブジェクト変数を理解するVBAで転記|ブック間で文字列をコピペするマクロの作り方を教えます