Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


19198 / 76734 ←次へ | 前へ→

【62972】Re:ファイルの抽出
発言  kanabun  - 09/9/28(月) 14:47 -

引用なし
パスワード
   ▼さくら さん:

>重複する質問で申し訳有りません&情報ありがとうございました!

neptune さんがリンクで紹介されているスレッドは主として
検索スピードが話題の中心でしたので、FindFirstFileW 系の
API高速検索を使っていますが、
同じロジックで Dir$関数の再帰処理によるサブフォルダの検索
も可能です。
参考まで。

Sub さくら3()
  Dim LookIn As String: LookIn = "D:\(Data)\" '◆検索Rootフォルダ
  Dim Filename As String: Filename = "*.xls"
  Dim FoundFiles() As String
  Dim nCount As Long
  Dim mCount As Long
  Dim i As Long
  
  'LookIn   : 検索Rootフォルダ
  'Filename  : 検索ファイル名
  'FoundFiles(): マッチしたファイル名の配列()
  'nCount   : ファイルの数
  FileSearch LookIn, Filename, FoundFiles(), nCount, mCount, 0
  
  If (nCount - mCount) > 0 Then
    With Worksheets
      With .Add(After:=.Item(.Count))
        .[A1].Resize(nCount, 2).Value = Trans(FoundFiles())
      End With
    End With
    MsgBox nCount - mCount & "個のファイルがマッチしました"
  End If
End Sub

' サブフォルダを含むファイルの検索
Sub FileSearch(ByVal strDir As String, strFind As String, _
        FoundFiles() As String, nCount As Long, _
        mCount As Long, ByVal Level As Long)

  Dim SubDirs() As String
  Dim strName  As String
  Dim lngCount As Long
  Dim i As Long

  If Right$(strDir, 1) <> "\" Then strDir = strDir & "\"
  strFind = LCase$(strFind)

  If Level <= 1 Then  'Rootフォルダおよび直下のサブフォルダのとき
    nCount = nCount + 1
    mCount = mCount + 1
    ReDim Preserve FoundFiles(1, 1 To nCount)
    FoundFiles(0, nCount) = strDir
  End If

  On Error GoTo err_Dir
  'サブフォルダ名を含む全てのファイルを検索
  strName = Dir$(strDir, vbDirectory Or vbReadOnly _
              Or vbHidden Or vbSystem)
  Level = Level + 1
  While Len(strName)
    If GetAttr(strDir & strName) And vbDirectory Then
      ' サブフォルダならば 配列に一時記憶
      If Not strName Like ".*" Then
         lngCount = lngCount + 1
         ReDim Preserve SubDirs(1 To lngCount)
         SubDirs(lngCount) = strName
      End If

    ElseIf LCase$(strName) Like strFind Then
      ' 検索ファイル名にマッチしたファイル
      nCount = nCount + 1
      ReDim Preserve FoundFiles(1, 1 To nCount)
      FoundFiles(1, nCount) = strName
    End If
Next_Dir:
    strName = Dir$()
  Wend

  ' サブフォルダ内の検索
  For i = 1 To lngCount
    FileSearch strDir & SubDirs(i), strFind, _
         FoundFiles(), nCount, mCount, Level
  Next
  Exit Sub
err_Dir:
  Debug.Print Err().Description, strDir & strName
  Resume Next_Dir
End Sub

'配列のTranspose
Private Function Trans(ff() As String) As String()
  Dim sv() As String
  Dim i As Long, n As Long
  n = UBound(ff, 2)
  ReDim sv(1 To n, 1)
  For i = 1 To n
    sv(i, 0) = ff(0, i)
    sv(i, 1) = ff(1, i)
  Next
  Trans = sv()
End Function

(注)Dir()関数はUnicodeファイル名に対応していないので、
   アラビア語やタイ語のファイル名があると失敗します。
   再帰処理プロシージャ内の
      On Error GoTo err_Dir
   は、そのエラー処理宣言です。

なお、同様の処理はFso(Scripting.FileSystemObject) でも可能ですが、
速度に問題があるので、個人的には Dirを使った再帰Loopのほうが
お手軽かと思います。
もちろん、リンク先の Unicode APIのほうがDir Loopより高速で
パスの長さに対する制限もありませんので、よく使う場合は そちらを
どうぞ(^^
2 hits

【62954】ファイルの抽出 さくら 09/9/25(金) 16:57 質問
【62955】Re:ファイルの抽出 neptune 09/9/25(金) 17:51 発言
【62970】Re:ファイルの抽出 さくら 09/9/28(月) 13:32 発言
【62972】Re:ファイルの抽出 kanabun 09/9/28(月) 14:47 発言
【62979】Re:ファイルの抽出 kanabun 09/9/28(月) 23:42 発言
【63023】Re:ファイルの抽出 さくら 09/10/1(木) 15:23 発言
【63026】Re:ファイルの抽出 kanabun 09/10/1(木) 20:24 発言
【63027】Re:ファイルの抽出 kanabun 09/10/1(木) 20:27 発言

19198 / 76734 ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free