質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

3回答

4679閲覧

VBA 指定フォルダの配下にあるファイルをすべて参照する処理について質問

King_of_Flies

総合スコア382

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

1クリップ

投稿2018/03/01 05:08

お世話になっております。

下記参考サイトを元に、コードを作成しました。

http://officetanaka.net/excel/vba/file/file07.htm
http://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub05_110_120.html

VBA

1Private Sub hoge(folderPath As String) 2 Dim targetFileName As String 3  'ファイル名格納① 4 targetFileName = Dir(folderPath & "*.xlsx",vbNormal) 5 6 Do while targetFileName <> "" 7 'openfileは渡されたファイル名を持つファイルを開く処理です。 8 Call openFile(targetFileName) 9 10 '新しく開かれたtargetFileNameのBookオブジェクトを格納 11 Dim targetWorkBook As WorkBook 12 Set targetWorkBook = ActiveWorkBook 13 14    '新しく開かれたtargetFileNameの一番目のシートオブジェクトを格納 15 Dim targetWorkSheet As WorkSheet 16     Set targetWorkSheet = targetWorkBook.WorkSheets(1) 17 18 'dataEditは渡されたシートオブジェクトのデータにいろいろ設定する 19 Call dataEdit(targetWorkSheet) 20    21 '開かれたファイルを閉じる 22 Application.DisplayAlerts = False 23 targetWorkBook.Close 24 Application.DisplayAlerts = True  25     26     '--問題となっているところ。ファイル名格納②-- 27 targetFileName = Dir() 28 Loop 29 30End Sub

説明しやすいように、前提として
folderPath には2件のファイル「ふげ.xlsx」「ほげ.xlsx」があるとします。

参考のサイトの意図する通りに動作するのであれば、
①の処理でふげ.xlsxがtargetFileNameに格納され、
②の処理でほげ.xlsxがtargetFileNameに格納されること思うのですが、
①の処理は上手く動作し、②の処理ではtargetFileNameに""が入っています。

なぜ「ほげ.xlsx」が取れないのでしょうか。
どうぞよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

このような場合は、まずはシンプルなコードで動作確認して、次にコードを順次追加していって動作確認するということを繰り返して原因を特定しましょう。

下記のようにファイル名検索以外の部分をコメントアウトした場合、
イミディエイトにファイル名は出力されますか。

されたら、一つずつコメントアウトを外して、動作確認してください。希望のファイル名が出力されない場合、直前にコメントアウトを外してコードが原因です。

vba

1Private Sub hoge(folderPath As String) 2 Dim targetFileName As String 3 'ファイル名格納① 4 targetFileName = Dir(folderPath & "*.xlsx", vbNormal) 5 6 Do While targetFileName <> "" 7 Debug.Print targetFileName 'イミディエイトウィンドウへファイル名を出力 8' 'openfileは渡されたファイル名を持つファイルを開く処理です。 9' Call openFile(targetFileName) 10' 11' '新しく開かれたtargetFileNameのBookオブジェクトを格納 12' Dim targetWorkBook As Workbook 13' Set targetWorkBook = ActiveWorkbook 14' 15' '新しく開かれたtargetFileNameの一番目のシートオブジェクトを格納 16' Dim targetWorkSheet As Worksheet 17' Set targetWorkSheet = targetWorkBook.Worksheets(1) 18' 19' 'dataEditは渡されたシートオブジェクトのデータにいろいろ設定する 20' Call dataEdit(targetWorkSheet) 21' 22' '開かれたファイルを閉じる 23' Application.DisplayAlerts = False 24' targetWorkBook.Close 25' Application.DisplayAlerts = True 26 27 '--問題となっているところ。ファイル名格納②-- 28 targetFileName = Dir() 29 Loop 30 31End Sub

原因の推測ですが、処理中にファイル名を変更したり、ファイル削除したりする処理が入ってませんか。

投稿2018/03/01 05:30

編集2018/03/01 09:05
hatena19

総合スコア33620

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

King_of_Flies

2018/03/01 05:40

hatenaさんの提示通りにコメントアウトし処理実行をしてみました。 コメントアウトした状態だとDir()は希望通りに動作しました。 おそらく原因はCall openFile(targetFileName)の箇所かなと考えています。 理由として openFileの関数の中で、 targetFileNameの呼び出し実行処理として 下記実装をしていて、 On Error Resume Next If Dir(filePath & fileName) <> "" Then Application.DisplayAlerts = False Workbooks.Open filePath & fileName Application.DisplayAlerts = True checkFileExists = True Else Call setMessageError(CommonUtil.createMessageParam1(MessageConstant.ERRMSG_NOTFOUND_FILE, fileName)) checkFileExists = False End If If Err <> 0 Then Err.Clear End If ここのIf分の条件でDir関数を使用しているからと思います。
ExcelVBAer

2018/03/01 05:43

余談ですが、こういったケースもあるので、自分は下記の関数を作成して使いまわしてます。 ・指定フォルダ内のファイル名orファイルパスを1次元配列で返す
jawa

2018/03/01 06:03 編集

私からも回答投稿してしまいましたが、ほぼ間違いなくループ前に行ったワイルドカード指定のDirがファイル名指定のDirで上書かれているのが原因ですね。 今回のhoge関数からの利用だけで考えれば、Dirで取得した(つまり存在することがわかっている)ファイル名をopenFile関数に渡しているので、開く前に改めて存在チェックをする必要性は薄いと思います。 それでも開く前にファイル存在チェックをしたいのなら、FileSystemObjectのFileExistsを使うという方法もあります。 openFile関数を変更したくない場合は、ExcelVBAerさんからのコメントにあるような方法など、ファイルをループする仕組みを変更する必要がありそうです。
hatena19

2018/03/01 06:24

Call先でDirを使っていたら、そりゃダメでしょう。そこまでは推測できなかった(;^ω^) Dirはこういうことがあるから注意しないと。ファイル名変更や削除,追加しても想定外の動作になることがありますので。 今回は、Call先でDir自体必要ないと思いますが、思わぬバグの危険性がありますので、先にファイル名一覧を取得してから、それに対して処理をするようにするのが吉ですね。 ExcelVBAerさんからのコメントの方法や、 http://officetanaka.net/excel/vba/file/file07.htm の最後の方の「FileSystemObjectで取得する」方法などを使うといいでしょう。
King_of_Flies

2018/03/01 08:43

皆様、ご回答ありがとうございます。 無事、解決いたしました。 今回は原因調査に一番役に立ちました「hatena19」様の回答をBAとさせていただきます。 ありがとうございました。
guest

0

この流れで2ファイル目が取得できないのなら、おそらくループ内の他の処理をすべて省いて

Dim targetFileName As String 'ファイル名格納① targetFileName = Dir(folderPath & "*.xlsx",vbNormal) Do while targetFileName <> "" '【確認用】取得ファイル名をメッセージ表示 Msgbox targetFileName '--問題となっているところ。ファイル名格納②-- targetFileName = Dir() Loop

としてもうまく取れないのではないでしょうか。
だとすれば怪しむべきはファイル名ということになるのですが。

Dirを疑う場合の確認事項

①2つめのファイル(ほげ.xlsx)はfolderPath内に存在していますか?
※↑さすがにこれは確認済みだと思いますが。。

②拡張子(半角で.xlsx)は正しいですか?
※↑例えば最近のマクロ付きブックは拡張子.xlsmです。
※このため様々なExcelブックを対象とする場合は拡張子*.xls*で抽出したりします。

targetFileName = Dir(folderPath & "*.*",vbNormal)でならファイル取得できますか?
※↑これは.xlsx以外も取得されるため、オープン処理などは省いた状態で確認する必要があります。

まずはこのあたりを確認してみてはいかがでしょうか。

その他の怪しい点

targetFileName = Dir()でtargetFileName=""が取得されており、その結果Loopを抜けて処理終了していることまで確認できているのなら、この線はないので読み飛ばしてください。

もし「2ファイル目の処理が行われていないからtargetFileName=""が取得されているのだろう」と推測されているのなら、ちょっと違う可能性もあります。

コードがないので何とも言えませんが
Call openFile(targetFileName)
でブックをオープンした後に
Set targetWorkBook = ActiveWorkBook
でアクティブなブックを今回開いたブックとして扱っています。

この手法はしばしば行われている方法ではありますが、確実ではありません。
もしマクロを実行しているブックが何かの拍子でアクティブとなり、アクティブワークブックとして取得されてしまったら、targetWorkBook.Closeの時点でマクロは中断されることになります。
今回の場合「2ファイル目の処理が行われない」という点では2つめのファイルが取得できていないのと同じように感じるかもしれません。

試に
Set targetWorkBook = ActiveWorkBook
のあとに
Msgbox targetWorkBook.Name
を実行してみてください。
1件目の処理でちゃんと"ふげ.xlsx"を対象としていますでしょうか?

なお、開いたブックを取得する場合は、Workbook.Openの引数を取得するのが一番確実です。
またExcelは同じ名前のファイルを同時には開けいないため、開いた後にWorkbooks("ブック名")で取得するのも有効です。

参考になれば幸いです。

投稿2018/03/01 05:47

jawa

総合スコア3013

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ファイルの属性が違うとか?
Dir(folderPath & "*.xlsx",vbNormal)
→ vbNormalだけ指定なので、隠しファイル、読取専用は対象外になりそう。

投稿2018/03/01 05:17

ExcelVBAer

総合スコア1175

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ExcelVBAer

2018/03/01 05:19

あと、パスが長すぎると取れなくなるケースがあります(255くらいだったかな?) ※これに関しては詳しくないので、ご自分で調べてください~
King_of_Flies

2018/03/01 05:26

パスが255を超えていることは無いので問題はないと思われます。 また、ファイルの属性が違うという件ですが、 ふげ.xlsxをコピーして作成した「ふげ -コピー.xlsx」をリネームして 「ほげ.xlsx」に変更しただけなので、これも考えにくいと思います。
ExcelVBAer

2018/03/01 05:35

では、hatena19 さんが提示してるように、途中の処理を省いて再現するかどうかですね~
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問