プロが教える店舗&オフィスのセキュリティ対策術

■質問内容

下記マクロで、Dir関数のループ中にサブルーチンでDir関数を使用しています。
この場合、Macro1のDir関数がリセット(?)されて、やりたいことができません。
この状況を解消するうまい方法はないでしょうか?
Macro1、Macro2ともファイル名はID以外は変動するためどちらもワイルドカードを使用ていします。

Sub Macro1()
 '所定のフォルダ内のファイルをループするマクロ
 
 Dim strPathName As String, strFilename As String
 
 strPathName = "C:\temp1"
 
 'Aから始まるファイルを取得
 strFilename = Dir(strPathName & "\A*.xlsx")
 
 '全ファイルループ
 Do While strFilename <> ""
  
  Call Macro2(strFilename)
  
  '次のファイル名を取得
  strFilename = Dir
 Loop

End Sub
Sub Macro2(strFilename As String)
 'strFilenameが持っているIDを取得して、別の対応ファイルを取得するマクロ
 
 Dim strID As String
 Dim targetFilename As String, targetPath As String
 
 'ファイル名に含まれているIDを取得
 targetID = Split(strFilename, "_")(1)
 
 '探し出すファイルが保存されているフォルダパス
 targetPath = "C:\temp2"
 
 '探し出すファイル名取得(IDを含んでいる)
 targetFilename = Dir(targetPath & "\*" & targetID & "*.xlsx")
 
End Sub


■動作環境
OS 名:Microsoft Windows 10 Pro
OS バージョン:10.0.16299 N/A ビルド 16299
OS 製造元:Microsoft Corporation
プロセッサ:Intel64 Family 6 Model 42 Stepping 7 GenuineIntel ~2400 Mhz
BIOS バージョン:TOSHIBA Version 2.20 , 2012/06/22
物理メモリの合計:3,988 MB
Excel バージョン:14.0.7192.5000(32ビット) Microsoft Office Standard 2010の一部


以上、ご存知の方ご教示いただければ幸いです。

質問者からの補足コメント

  • みなさま回答ありがとうございます。
    この記載の方法は無理なのは把握しているのですが、やりたいことを伝えるためにかいております。
    やりたいことをどのようにすればやれるかを模索しているところですm(_ _)m

      補足日時:2019/08/27 21:05

A 回答 (6件)

Macro1のみFileSystemObjectを使用する方法に変えました。


Macro2のなかでDir()が使用可能になります。
参照設定でMicrosoft Scripting Runtimeにチェックをいれてから、実行してください。
Sub Macro1()
'所定のフォルダ内のファイルをループするマクロ

Dim strPathName As String, strFilename As String
Dim wfso As New FileSystemObject
Dim wfolder As Folder
Dim wfiles As Files
Dim wfile As File
strPathName = "C:\temp1"

Set wfolder = wfso.getfolder(strPathName)
Set wfiles = wfolder.Files
'取得したファイル一覧について処理
For Each wfile In wfiles
'A*.xlsxにマッチするファイルのみ処理する
If LCase(wfile.Name) Like "a*.xlsx" Then
Call Macro2(wfile.Name)
End If
Next

End Sub
「VBA Dir関数でファイルをループして」の回答画像5
    • good
    • 2
この回答へのお礼

ご回答ありがとうございます。
これでやりたことができました!!
ありがとうございました!!

お礼日時:2019/09/07 15:26

dir関数は多重にできないので、外側のループの処理結果を配列やCollectionに取得しておく必要があります。


質問の処理をCollectionを使って置き換える場合です。
出来るだけ元のプログラムを残しています。
Macro2はそのままです。

Sub Macro1()
'所定のフォルダ内のファイルをループするマクロ
Dim strPathName As String, strFilename As String
strPathName = "C:\temp1"
'Aから始まるファイルを取得
strFilename = Dir(strPathName & "\A*.xlsx")
'対象ファイル取得
Dim co As New Collection 'ファイル名記憶用Collection
Do While strFilename <> ""
'Collectionに追加
co.Add strFilename
'次のファイル名を取得
strFilename = Dir
Loop
'全ファイルループ
Dim f As Variant
'Collectionの値を順に
For Each f In co
'Macro2にCollectionの値を渡す
Call Macro2(CStr(f))
Next
End Sub
    • good
    • 2
この回答へのお礼

ご回答ありがとうございます。
今回はFSOで対応しましたが、勉強になりました!!

お礼日時:2019/09/07 15:26

'Aから始まるファイルを取得


strFilename = Dir(strPathName & "\A*.xlsx")
'全ファイルループ
Do While strFilename <> ""
  'ファイル名を配列に格納
  ReDim Preserve 配列(i)
  配列(i) = strFilename
  i = i + 1
  '次のファイル名を取得
  strFilename = Dir()
Loop
'配列をループ
For i = 0 To UBound(配列)
  Call Macro2(配列(i))
Next i
    • good
    • 1
この回答へのお礼

ご回答ありがとうございます。
今回はFSOで対応させていただきました!
ありがとうございました!

お礼日時:2019/09/07 15:27

私もその方法は無理と思います。



Dir(~)に設定がされている場合、次を探す =Dir() の検索条件は直近で指定したもののはずです。
今回ですと Dir(targetPath & "\*" & targetID & "*.xlsx")

なのでFileSystemObject を使うのではないかと。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
FSOで対応させていただきました!

お礼日時:2019/09/07 15:27

こんにちは!



未検証ですが・・・

>strFilename = Dir
の次に
>strFilename = Dir()

の1行を追加したらどうなりますか?

当方の記憶ではループの前に
一旦Dir関数の中身を空にする必要があったと思うのですが・・・m(_ _)m
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
FSOで対応させていただきました!

お礼日時:2019/09/07 15:27

その使い方は無理。


別物扱いになる。
はず。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
FSOで対応させていただきました!

お礼日時:2019/09/07 15:27

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A