3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Excel VBAでフォルダやファイルを操作する関数集

Last updated at Posted at 2023-12-22

概要

  • Excel VBAで、フォルダやファイルを操作するためのコード集を作成しました。条件に当たるファイルのフルパスをすべて取得する関数など、利用すると便利です。

コードに関する動画

  • 以下の動画でこのコードを使いました。

実行環境

以下の環境で動作確認をしました。

  • Windows11でのExcel 2021

注意

  • プログラムの実行については、すべて自己責任で行ってください。実行により発生した、いかなる直接的または間接的被害について、作者はその責任を負いません。

各コード(関数)について

今回ご紹介するコードは、「フォルダ操作に関すること」および「ファイル操作に関すること」の2つです。それぞれについて、目的に応じた関数を作成しました。

  • フォルダ操作に関すること
    • 特定の親フォルダ内で、特定の名前がついたサブフォルダのフルパスリストを返す関数
    • フォルダ名を変更する関数
    • フォルダをコピーする関数
    • 新しいフォルダを作成する関数
    • フォルダを開く関数

  • ファイル操作に関すること
    • 特定のフォルダ内で、特定の名前がついたファイルのフルパスリストを返す関数
    • ファイル名を変更する関数
    • ファイルをコピーする関数
    • ファイルに関する情報を取得する関数

実行例

  • 以下のテスト用関数を参考にしてみてください。具体的なパス名などは、仮の値("Your_Path_Here"、"Name_Here")が入っているので、変更してください。
テスト用関数
Option Explicit

' GetFolderList関数のテスト
Sub TestGetFolderList()
    ' 指定フォルダ内の指定条件に合致するフォルダのリスト
    Dim folderList() As Variant
    ' 親フォルダのパス
    Dim ParentFolderPath As String
    ' フォルダ名の部分名
    Dim FolderPartName As String
    
    ' 親フォルダのパスを設定
    ParentFolderPath = "Your_Path_Here"
    
    ' フォルダ名を設定
    FolderPartName = "Name_Here"
    
    ' GetFolderList関数を呼び出してフォルダリストを取得
    folderList = GetFolderList(ParentFolderPath, FolderPartName)
    
    ' デバッグに出力
    ' Debug.Print "配列の上限: " & UBound(folderList)
    ' Debug.Print "配列の下限: " & LBound(folderList)

    Dim i As Long

    ' 配列のすべての要素をデバッグに出力
    For i = LBound(folderList) To UBound(folderList)
        Debug.Print "Index " & i & ": " & folderList(i)
    Next i
End Sub

' フォルダ名を変更するサブプロシージャのテスト
Sub TestChangeFolderName()
    ' 変更対象フォルダのフルパス
    Dim FolderFullPath As String
    ' 変更前のフォルダ名の部分名
    Dim BeforeName As String
    ' 変更後のフォルダ名の部分名
    Dim AfterName As String

    ' テスト用の変数に値を設定
    FolderFullPath = "Your_Path_Here"

    BeforeName = "Name_Here"
    AfterName = Format(Date, "yyyymmdd") & "_ Name_Here"

    ' フォルダ名を変更するサブプロシージャを呼び出し
    Call ChangeFolderName(FolderFullPath, BeforeName, AfterName)
End Sub

Sub TestCopyFolder()
    Dim SourcePath As String ' コピー元フォルダのパス
    Dim NewFolderPath As String ' コピー先フォルダのパス
    
    ' コピー元フォルダのパス
    SourcePath = "Your_Path_Here"

    ' コピー後のフォルダのフルパス
    NewFolderPath = "Your_Path_Here"

    ' テスト対象のサブプロシージャを呼び出し
    Call CopyFolder(SourcePath, NewFolderPath)
End Sub

Sub TestMakeFolder()
    ' テストする変数を定義
    Dim folderName As String
    
    ' 変数に値を設定
    folderName = "Your_Path_Here"

    ' テストする関数を呼び出し
    Call MakeFolder(folderName)
End Sub

Sub TestOpenFolder()
    ' テストする変数を定義
    Dim folderPath As String
    
    ' 変数に値を設定
    folderPath = "Your_Path_Here"

    ' テストする関数を呼び出し
    Call OpenFolder(folderPath)
End Sub

Sub TestGetFileList()
    ' テストする変数を定義
    Dim fileList() As Variant
    Dim ParentFolderPath As String
    Dim FilePartName As String
    Dim i As Long

    ' 親フォルダのパスを設定
    ParentFolderPath = "Your_Path_Here"

    ' ファイル名の部分名を設定
    FilePartName = "Name_Here"

    ' GetFileList関数を呼び出してファイルリストを取得
    fileList = GetFileList(ParentFolderPath, FilePartName)

    ' ファイルリストの要素数をデバッグに出力
    Debug.Print "Number of files: " & UBound(fileList) - LBound(fileList) + 1

    ' ファイルリストのすべての要素をデバッグに出力
    For i = LBound(fileList) To UBound(fileList)
        Debug.Print "Index " & i & ": " & fileList(i)
    Next i
End Sub

Sub TestChangeFileName()
    ' テストする変数を定義
    Dim FilePath As String
    Dim NewFileName As String

    ' ファイルのパスを設定
    FilePath = "Your_Path_Here"

    ' 新しいファイル名を設定
    NewFileName = Format(Date, "yyyymmdd") & "File_Name"

    ' ChangeFileNameサブプロシージャを呼び出してファイル名を変更
    Call ChangeFileName(FilePath, NewFileName)
End Sub

Sub TestCopyFile()
    ' テストする変数を定義
    Dim SourceFilePath As String
    Dim NewFileName As String

    ' コピー元のファイルパスを設定
    SourceFilePath = "Your_Path_Here"

    ' コピー先のファイルパスを設定
    NewFileName = "Your_Path_Here"

    ' CopyFileサブプロシージャを呼び出してファイルをコピー
    Call CopyFile(SourceFilePath, NewFileName)
End Sub

Sub TestGetFileInfo()
    ' テストする変数を定義
    Dim FilePath As String
    Dim InfoType As String
    Dim result As String

    ' ファイルのパスを設定
    FilePath = "Your_Path_Here"

    ' 取得する情報の種類を設定
    InfoType = "ファイル名"
    ' GetFileInfo関数を呼び出して結果を取得
    result = GetFileInfo(FilePath, InfoType)
    ' 結果をデバッグ
    Debug.Print InfoType & ": " & result

    ' テストする変数を再設定
    InfoType = "ディレクトリ名"
    ' GetFileInfo関数を呼び出して結果を取得
    result = GetFileInfo(FilePath, InfoType)
    ' 結果をデバッグ
    Debug.Print InfoType & ": " & result
    
    ' テストする変数を再設定
    InfoType = "拡張子なしファイル名"
    ' GetFileInfo関数を呼び出して結果を取得
    result = GetFileInfo(FilePath, InfoType)
    ' 結果をデバッグ
    Debug.Print InfoType & ": " & result

    ' テストする変数を再設定
    InfoType = "拡張子"
    ' GetFileInfo関数を呼び出して結果を取得
    result = GetFileInfo(FilePath, InfoType)
    ' 結果をデバッグ
    Debug.Print InfoType & ": " & result
End Sub
    

  • 以下、フォルダやファイルを操作するための、汎用的に利用する関数をご紹介します。
汎用関数
Option Explicit
'------------フォルダに関すること------------------------------------------------------

' 特定の親フォルダ内で、特定の名前がついたサブフォルダのフルパスリストを返す関数
Function GetFolderList(ByVal ParentFolderPath As String, ByVal FolderPartName As String) As Variant
  ' ParentFolderPath: 親フォルダのパス
  ' FolderPartName: フォルダ名の部分名
  Dim fso As Object
  Dim folderList() As Variant ' フォルダリストの配列
  Dim i As Long
  i = 1 ' 配列のインデックス

  ' FileSystemObjectを作成
  Set fso = CreateObject("Scripting.FileSystemObject")

  Dim folderObject As Object
  Dim foundFolders As Boolean ' フォルダが見つかったかどうかを示すフラグ
  foundFolders = False

  For Each folderObject In fso.GetFolder(ParentFolderPath).SubFolders
    ' フォルダ名が指定条件に合致する場合
    If InStr(fso.GetBaseName(folderObject.Path), FolderPartName) <> 0 Then
      ' 配列のサイズを1増やし(ReDimによる変更)、既存のデータを保持(Preserve)
      ReDim Preserve folderList(1 To i)
      folderList(i) = folderObject.Path
      i = i + 1
      foundFolders = True
    End If
  Next

  ' FileSystemObjectを解放
  Set fso = Nothing

  ' フォルダが見つからなかった場合の処理
  If Not foundFolders Then
    Debug.Print "フォルダが見つかりません。"
    Stop ' 処理を停止
    End
  End If

  ' 結果の配列を返す
  GetFolderList = folderList
End Function


' フォルダ名を変更する関数
Function ChangeFolderName(ByVal FolderFullPath As String, ByVal BeforeName As String, ByVal AfterName As String)
  ' FolderFullPath: フォルダのフルパス
  ' BeforeName: 変更前のフォルダ部分名
  ' AfterName: 変更後のフォルダ部分名
  Dim fso As Object
  Dim NewFolderName As String
   
  ' FileSystemObjectを作成
  Set fso = CreateObject("Scripting.FileSystemObject")
   
  ' 変更前のフォルダ名を取得
  Dim CurrentFolderName As String
  CurrentFolderName = fso.GetFolder(FolderFullPath).Name
   
  ' 変更後のフォルダ名
  NewFolderName = Replace(CurrentFolderName, BeforeName, AfterName)
   
  ' フォルダ名を変更
  fso.GetFolder(FolderFullPath).Name = NewFolderName
   
  ' FileSystemObjectを解放
  Set fso = Nothing
   
  ' 変更後のフォルダ名を返す
  Debug.Print "変更後のフォルダ名: " & NewFolderName
End Function


' フォルダをコピーする関数
Function CopyFolder(ByVal CopyFromPath As String, ByVal CopyToPath As String)
  ' CopyFromPath: コピー元フォルダのパス
  ' CopyToPath:   コピー後のフォルダのフルパス
  Dim fso As Object
   
  ' コピー先のフォルダが存在しない場合
  If Dir(CopyToPath, vbDirectory) = "" Then
    ' FileSystemObjectを作成
    Set fso = CreateObject("Scripting.FileSystemObject")
     
    ' フォルダをコピー
    fso.CopyFolder CopyFromPath, CopyToPath
     
    ' FileSystemObjectを解放
    Set fso = Nothing
  Else
    ' コピー先のフォルダが既に存在する場合は何もしない
  End If
End Function



' 新しいフォルダを作成する関数
Function MakeFolder(ByVal folderName As String)
  ' FolderName: 作成するフォルダの名前
  ' フォルダが存在しないかどうかを確認
  If Dir(folderName, vbDirectory) = "" Then
    ' フォルダが存在しない場合は新しいフォルダを作成
    MkDir folderName
  Else
    ' フォルダが既に存在する場合は何もしない
  End If
End Function


' フォルダを開く関数
Function OpenFolder(ByVal folderPath As String)
  ' FolderPath: 開くフォルダのパス
  Dim shell As Object
   
  ' フォルダが存在するか確認
  If Dir(folderPath, vbDirectory) = "" Then
    Debug.Print "指定されたフォルダが存在しません: " & folderPath
    Stop ' 処理を停止
    End
  End If
   
  ' WScript.Shellオブジェクトを作成
  Set shell = CreateObject("WScript.Shell")
   
  ' フォルダを開く
  shell.Run folderPath
   
  ' WScript.Shellオブジェクトを解放
  Set shell = Nothing
End Function


'------------ファイルに関すること------------------------------------------------------

' 特定のフォルダ内で、特定の名前がついたファイルのフルパスリストを返す関数
Function GetFileList(ByVal folderPath As String, ByVal FilePartName As String) As Variant
  ' FolderPath: ファイルを検索するフォルダのパス
  ' FilePartName: ファイル名の部分名
  Dim fso As Object
  Dim fileList() As Variant ' ファイルリストの配列
  Dim i As Long
  i = 1 ' 配列のインデックス

  ' FileSystemObjectを作成
  Set fso = CreateObject("Scripting.FileSystemObject")

  Dim fileObject As Object
  Dim foundFiles As Boolean ' ファイルが見つかったかどうかを示すフラグ
  foundFiles = False

  For Each fileObject In fso.GetFolder(folderPath).Files
    ' ファイル名が指定条件に合致する場合
    If InStr(fso.GetFileName(fileObject.Path), FilePartName) <> 0 Then
      ' 配列のサイズを1増やし(ReDimによる変更)、既存のデータを保持(Preserve)
      ReDim Preserve fileList(1 To i)
      fileList(i) = fileObject.Path
      i = i + 1
      foundFiles = True
    End If
  Next

  ' FileSystemObjectを解放
  Set fso = Nothing

  ' ファイルが見つからなかった場合の処理
  If Not foundFiles Then
    Debug.Print "ファイルが見つかりません。"
    Stop ' 処理を停止
    End
  End If

  ' 結果の配列を返す
  GetFileList = fileList
End Function


' ファイル名を変更する関数
Function ChangeFileName(ByVal FilePath As String, ByVal NewFileName As String)
  ' FilePath: ファイルのフルパス
  ' NewFileName: 変更後のファイル名
  Dim fso As Object
  Dim targetFile As Object
   
  ' FileSystemObjectを作成
  Set fso = CreateObject("Scripting.FileSystemObject")
   
  ' 変更対象のファイルを取得
  Set targetFile = fso.GetFile(FilePath)
   
  ' ファイルが存在するか確認
  If targetFile Is Nothing Then
    Debug.Print "ファイルが存在しません。"
    Stop ' 処理を停止
    End
  Else
    ' ファイル名を変更
    targetFile.Name = NewFileName
  End If
   
  ' FileSystemObjectを解放
  Set fso = Nothing
End Function


' ファイルをコピーする関数
Function CopyFile(ByVal SourceFilePath As String, ByVal NewFilePath As String)
  ' SourceFilePath: コピー元ファイルのパス
  ' NewFilePath: コピー先ファイルのパス
  Dim response As Long
   
  ' コピー先に同名のファイルが存在するか確認
  If Dir(NewFilePath) <> "" Then
    ' ユーザーに確認メッセージを表示
    response = MsgBox("同名のファイルが存在します。" & vbCrLf & _
      "上書きしますか?", vbYesNo)
     
    ' Noが選択された場合は終了
    If response = vbNo Then Exit Function
  End If
   
  ' ファイルをコピー
  FileCopy SourceFilePath, NewFilePath
End Function


' ファイルに関する情報を取得する関数
Function GetFileInfo(ByVal FilePath As String, ByVal InfoType As String) As String
  ' FilePath: ファイルのパス
  ' InfoType: 取得する情報の種類
  Dim objFSO As Object
  Set objFSO = CreateObject("Scripting.FileSystemObject")
   
  ' ディレクトリ名を取得
  If InfoType = "ディレクトリ名" Then
    GetFileInfo = objFSO.GetParentFolderName(FilePath)
   
  ' ファイル名を取得
  ElseIf InfoType = "ファイル名" Then
    GetFileInfo = objFSO.GetFileName(FilePath)
   
  ' ファイル名(拡張子を除く)を取得
  ElseIf InfoType = "拡張子なしファイル名" Then
    GetFileInfo = objFSO.GetBaseName(FilePath)
   
  ' 拡張子が何か取得
  ElseIf InfoType = "拡張子" Then
    GetFileInfo = objFSO.GetExtensionName(FilePath)
   
  ' 不明な InfoType が指定された場合は空文字列を返す
  Else
    Debug.Print "未知の InfoType が指定されました: " & InfoType
    Stop ' 処理を停止
    End
  End If
   
  ' FileSystemObjectを解放
  Set objFSO = Nothing
End Function
3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?