目安箱 IV

目安箱投稿のルールはこちらをごらんください。
ご意見は電子メールで承っています。
「目安箱」は質問禁止です。技術的な質問はそれぞれの質問箱へどうぞ。

迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。

  新規投稿 ┃ツリー表示 ┃一覧表示 ┃トピック表示 ┃検索 ┃設定 ┃ホーム  
105 / 118 ツリー ←次へ | 前へ→

【74】FilePathを列挙するサンプル ちゃっぴ 04/9/13(月) 23:57 全般[未読]
【75】Re:FilePathを列挙するサンプル ちゃっぴ 04/9/14(火) 0:03 全般[未読]
【76】FilePathを列挙するサンプル(API) ちゃっぴ 04/9/14(火) 1:37 全般[未読]
【77】Re:FilePathを列挙するサンプル(API) ちゃっぴ 04/9/14(火) 1:50 全般[未読]

【74】FilePathを列挙するサンプル
全般  ちゃっぴ  - 04/9/13(月) 23:57 -

引用なし
パスワード
   Jakaさんが一人でがんばっているみたいなので・・・
私も一点。

FAQであるFilePathを列挙するサンプルです。

【その1 FSO Version】

【要参照】「Microsoft Scripting Runtime」

'呼び出し用
Sub CallFilePathList1()
  Dim objFSO     As FileSystemObject
  Dim strTargetPath  As String      '対象フォルダパス
  
  Set objFSO = New FileSystemObject
  
  Call EnumFilePathList1(objFSO.GetFolder(strTargetPath))
End Sub

'本体
Sub EnumFilePathList1(objFolder As Folder)
  Dim objTargetFile  As File
  Dim objSubFolder   As Folder
  
  'ファイル名を列挙
  For Each objTargetFile In objFolder.Files
    Debug.Print objTargetFile.Path
  Next objTargetFile
  
  'サブフォルダを検索
  For Each objSubFolder In objFolder.SubFolders
    Call EnumFilePathList1(objSubFolder)
  Next objSubFolder
End Sub

非常にシンプルで不具合も少ないのですが、
速度が非常に遅いのがネックです。
(初心者にもっともお勧め・・・)

【75】Re:FilePathを列挙するサンプル
全般  ちゃっぴ  - 04/9/14(火) 0:03 -

引用なし
パスワード
   【その2 コマンドプロンプトDIRコマンド Version】

【要参照】「Windows Scripting Host Object Model」

Sub EnumFilePathList()
  Dim objWshShell   As wshShell
  Dim objFSO     As FileSystemObject
  Dim objRedirectFile As File
  Dim objRedirectTXT As TextStream
  Dim strTargetPath  As String    '対象フォルダパス
  Dim strRedirectPath As String    '一時ファイルパス
  Dim lngReturn    As Long
  Dim varFileList   As Variant
  Dim varFilePath   As Variant
  
  Set objWshShell = New wshShell
  Set objFSO = New FileSystemObject
  
  lngReturn = objWshShell.Run("CMD /C DIR """ & strTargetPath _
    & """ /A-D /B /S > """ & strRedirectPath & """", 7, True)
  Set objWshShell = Nothing

  If lngReturn = 0 Then
    Set objRedirectFile = objFSO.GetFile(strRedirectPath)
    Set objRedirectTXT = objRedirectFile.OpenAsTextStream
    
    varFileList = Split(objRedirectTXT.ReadAll)
    
    For Each varFilePath In varFileList
      Debug.Print varFilePath
    Next varfilpath
    
    objRedirectTXT.Close
    objRedirectFile.Delete
    
    Set objRedirectTXT = Nothing
    Set objRedirectFile = Nothing
  End If
  Set objFSO = Nothing
End Sub

ファイルの入出力を介しますが、FSOよりも動作が速いのが魅力です。
また、サブフォルダの検索のOn/Offをオプション"/S"だけで
切り替えられるのも魅力です。

ただ、残念なことにOSに依存します。

【76】FilePathを列挙するサンプル(API)
全般  ちゃっぴ  - 04/9/14(火) 1:37 -

引用なし
パスワード
   Win32API FindFirstFile(A)を使ったサンプルです。

【EnumFilePathList3】をコールしてお使いください。


Const INVALID_HANDLE_VALUE   As Long = (-1)       '無効なFile Handle値

'ファイル属性
Const FILE_ATTRIBUTE_DIRECTORY As Long = &H10       'フォルダ

Const MAX_PATH         As Long = 260&       'パスの最大長

'WIN32_FIND_DATA構造体(ディレクトリエントリ(ファイル情報))
Private Type WIN32_FIND_DATA
  dwFileAttributes  As Long         'ファイル属性
  ftCreationTime   As Currency       '作成日時
  ftLastAccessTime  As Currency       '最終アクセス日時
  ftLastWriteTime   As Currency       '最終更新日時
  nFileSizeHigh    As Long         'ファイルサイズの上位32bit値
  nFileSizeLow    As Long         'ファイルサイズの下位32bit値
  dwReserved0     As Long         '予約(現状なし)
  dwReserved1     As Long         '予約(現状なし)
  cFileName      As String * MAX_PATH  'ロングファイル名
  cAlternate     As String * 14     'ショートファイル名(8+3文字)
End Type

'-------------------------------------------------------------------------------------------
'[FindFirstFile]                文字列と一致するファイルを検索する
'
'戻り値                     成功:検索ハンドル(Long)
'                        失敗:INVALID_HANDLE_VALUE(-1)
'
'引数        lpFileName         パス名文字列のポインタ(Long)
'          lpFindFileData       検索結果([WIN32_FIND_DATA]構造体)
'-------------------------------------------------------------------------------------------
Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileW" _
                (ByVal lpFileName As String, _
                 lpFindFileData As WIN32_FIND_DATA) As Long

'-------------------------------------------------------------------------------------------
'[FindNextFile]                 [FindFirstFile]から継続してファイルを検索する
'                        (Unicode版)
'
'戻り値                     成功:検索ハンドル(Long)
'                        失敗:0
'
'引数        lpFileName         パス名文字列のポインタ(Long)
'          lpFindFileData       検索結果([WIN32_FIND_DATA]構造体)
'-------------------------------------------------------------------------------------------
Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileW" _
                (ByVal hFindFile As Long, _
                 lpFindFileData As WIN32_FIND_DATA) As Long
                
'-------------------------------------------------------------------------------------------
'[FindClose]                  [FindFirstFile]ハンドルをクローズする
'
'戻り値                     0:失敗, 0以外:成功
'
'引数        hFindFile          対象検索ハンドル(Long)
'-------------------------------------------------------------------------------------------
Private Declare Function FindClose Lib "kernel32" _
                (ByVal hFindFile As Long) As Long

'*******************************************************************************************
'[EnumFilePathList3]
'
'引数        strSearchPath        検索対象パス名(String)
'          strSearchBaseName      検索対象ファイル名(String)
'          strSearchExtention     検索対象拡張子(String)
'*******************************************************************************************
Sub EnumFilePathList3(ByVal strSearchPath As String, _
           Optional ByVal strSearchBaseName As String = "*", _
           Optional ByVal strSearchExtention As String = "*")

  Dim udtWin32FindData    As WIN32_FIND_DATA   '[WIN32_FIND_DATA]構造体(検索結果)
  Dim lngFindFileHandle    As Long         '[FindFirstFile]のハンドル
  Dim strFindFileName     As String        '検索結果ファイル名
  Dim lngResultCode      As Long         'APIのエラーコード
  
  '検索フルパス名を生成
  strSeachFullPath = strSearchPath _
    & "\" & strSearchBaseName & "." & strSearchExtention

  '文字列に一致するファイルを検索し、WIN32_FIND_DATA構造体に値を代入
  lngFindFileHandle = FindFirstFile(strSeachFullPath, udtWin32FindData)

  '検索結果ファイルハンドルが無効な場合終了
  If lngFindFileHandle <> INVALID_HANDLE_VALUE Then
    Do
      'ファイル名からNull文字を削除し格納
      strFindFileName = udtWin32FindData.cFileName
      strFindFileName = Left$(strFindFileName, InStr(strFindFileName, vbNullChar) - 1)
      
      'ファイル名が現在のフォルダ"."及び上位フォルダ".."でない場合
      If strFindFileName <> "." And strFindFileName <> ".." Then
        'ファイルの属性がディレクトリの場合
        If udtWin32FindData.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY Then
          'サブフォルダを検索(再帰呼び出し)
          Call EnumFilePathList4(strSearchPath & "\" & strFindFileName, _
                    strSearchBaseName, strSearchExtention)
        Else
          Debug.Print strSearchPath & "\" & strFindFileName
        End If
      End If
    ' 継続してファイルを検索
    Loop Until FindNextFile(lngFindFileHandle, udtWin32FindData) = 0
  End If
  
  'ファイルハンドルをクローズ
  lngResultCode = FindClose(lngFindFileHandle)
End Sub

難易度はかなり高めですが、速度は驚きです。
DIRコマンドと同じくファイル名にワイルドカードを使用して、
フィルタリングすることが可能です。

ただ、ANSI版ですので、パス名にUnicode拡張文字が使用されていた場合、
エラーになります。
NT系のOSを使用している場合には、後述のFindFirstFile(W)を
使用したほうがよいでしょう。

【77】Re:FilePathを列挙するサンプル(API)
全般  ちゃっぴ  - 04/9/14(火) 1:50 -

引用なし
パスワード
   Win32API FindFirstFile(W)を使ったサンプルです。
【EnumFilePathList4】をコールしてお使いください。


Const INVALID_HANDLE_VALUE   As Long = (-1)       '無効なFile Handle値

'ファイル属性
Const FILE_ATTRIBUTE_DIRECTORY As Long = &H10       'フォルダ

Const MAX_PATH         As Long = 260&       'パスの最大長
Const conUnicodeMaxPath     As Long = MAX_PATH * 2 - 1 'Unicodeでのパス最大長

'WIN32_FIND_DATA構造体(ディレクトリエントリ(ファイル情報))
Private Type WIN32_FIND_DATA
  dwFileAttributes      As Long       'ファイル属性
  ftCreationTime       As Currency     '作成日時
  ftLastAccessTime      As Currency     '最終アクセス日時
  ftLastWriteTime       As Currency     '最終更新日時
  nFileSizeHigh        As Long       'ファイルサイズの上位32bit値
  nFileSizeLow        As Long       'ファイルサイズの下位32bit値
  dwReserved0         As Long       '予約(現状なし)
  dwReserved1         As Long       '予約(現状なし)
  cFileName(MAX_PATH * 2 - 1) As Byte       'ロングファイル名
  cAlternate(14 * 2 - 1)   As Byte       'ショートファイル名(8+3文字)
End Type

'-------------------------------------------------------------------------------------------
'[FindFirstFile]                文字列と一致するファイルを検索する
'                        (Unicode版)
'
'戻り値                     成功:検索ハンドル(Long)
'                        失敗:INVALID_HANDLE_VALUE(-1)
'
'引数        lpFileName         パス名文字列のポインタ(Long)
'          lpFindFileData       検索結果([WIN32_FIND_DATA]構造体)
'-------------------------------------------------------------------------------------------
Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileW" _
                (ByVal lpFileName As Long, _
                 lpFindFileData As WIN32_FIND_DATA) As Long

'-------------------------------------------------------------------------------------------
'[FindNextFile]                 [FindFirstFile]から継続してファイルを検索する
'                        (Unicode版)
'
'戻り値                     成功:検索ハンドル(Long)
'                        失敗:0
'
'引数        lpFileName         パス名文字列のポインタ(Long)
'          lpFindFileData       検索結果([WIN32_FIND_DATA]構造体)
'-------------------------------------------------------------------------------------------
Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileW" _
                (ByVal hFindFile As Long, _
                 lpFindFileData As WIN32_FIND_DATA) As Long
                
'-------------------------------------------------------------------------------------------
'[FindClose]                  [FindFirstFile]ハンドルをクローズする
'
'戻り値                     0:失敗, 0以外:成功
'
'引数        hFindFile          対象検索ハンドル(Long)
'-------------------------------------------------------------------------------------------
Private Declare Function FindClose Lib "kernel32" _
                (ByVal hFindFile As Long) As Long

'*******************************************************************************************
'[EnumFilePathList4]
'
'引数        strSearchPath        検索対象パス名(String)
'          strSearchBaseName      検索対象ファイル名(String)
'          strSearchExtention     検索対象拡張子(String)
'*******************************************************************************************
Sub EnumFilePathList4(ByVal strSearchPath As String, _
           Optional ByVal strSearchBaseName As String = "*", _
           Optional ByVal strSearchExtention As String = "*")

  Dim udtWin32FindData    As WIN32_FIND_DATA   '[WIN32_FIND_DATA]構造体(検索結果)
  Dim lngFindFileHandle    As Long         '[FindFirstFile]のハンドル
  Dim strFindFileName     As String        '検索結果ファイル名
  Dim lngResultCode      As Long         'APIのエラーコード
  
  '検索フルパス名を生成
  strSeachFullPath = IIf(strSearchPath Like "\\*", "\\?\UNC" & _
    Mid$(strSearchPath, 2), "\\?\" & strSearchPath) _
    & "\" & strSearchBaseName & "." & strSearchExtention

  '文字列に一致するファイルを検索し、WIN32_FIND_DATA構造体に値を代入
  lngFindFileHandle = FindFirstFile(StrPtr(strSeachFullPath), udtWin32FindData)

  '検索結果ファイルハンドルが無効な場合終了
  If lngFindFileHandle <> INVALID_HANDLE_VALUE Then
    Do
      'ファイル名からNull文字を削除し格納
      strFindFileName = CStr(udtWin32FindData.cFileName)
      strFindFileName = Left$(strFindFileName, InStr(strFindFileName, vbNullChar) - 1)
      
      'ファイル名が現在のフォルダ"."及び上位フォルダ".."でない場合
      If strFindFileName <> "." And strFindFileName <> ".." Then
        'ファイルの属性がディレクトリの場合
        If udtWin32FindData.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY Then
          'サブフォルダを検索(再帰呼び出し)
          Call EnumFilePathList4(strSearchPath & "\" & strFindFileName, _
                    strSearchBaseName, strSearchExtention)
        Else
          Debug.Print strSearchPath & "\" & strFindFileName
        End If
      End If
    ' 継続してファイルを検索
    Loop While FindNextFile(lngFindFileHandle, udtWin32FindData)
  End If
  
  'ファイルハンドルをクローズ
  lngResultCode = FindClose(lngFindFileHandle)
End Sub

Unicode版FindFirstFileを使用したサンプルです。
Unicode版なのでWindows2000以降限定です。

速度に関しては言うまでもありません。
これが使えこなせれば、いうことはないでしょう。

他にもDir関数、FileSearchオブジェクト等ファイル検索するものは
ありますが、問題があるため推奨しません。

  新規投稿 ┃ツリー表示 ┃一覧表示 ┃トピック表示 ┃検索 ┃設定 ┃ホーム  
105 / 118 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:   
0
(SS)C-BOARD v3.8 is Free