カテゴリー: FileSystemObject

FileSystemObjectオブジェクトについて記載します

詳細なリファレンスを付けれたら、より分かりやすいのでしょうが、それは時間のある時にやろうと思います

  • VBA GetDriveNameの使い方と活用法|ドライブ名とパス抽出

    VBA GetDriveNameの使い方と活用法|ドライブ名とパス抽出

    調べてはみましたけど、正直、何に使うのかよくわからないメソッドですw

    ■GetDriveNameメソッド

    指定したパスからドライブの文字列を取得してくれるのだそうです

    ・構文

    構文は以下の通りです

    object.GetDriveName (path)

    objectはFileSystemObjectのオブジェクトです

    ・パラメータ

    メソッドのパラメータは以下の通りです

    • path … ドライブ名を取得するパスを指定

    パスとしては、存在しないドライブのパスも指定できてしまいます!

    どういうこと!?w

    これでドライブ名を取得してから、DriveExistsメソッドでドライブの存在確認をしないといけないのだろうか?

    ・戻り値

    メソッドの戻り値は以下の通りです

    • ドライブ名

    そのままですけど、ドライブ名が返りますが、Cドライブの場合は「C:」という風にドライブのアルファベットとコロンが返ります

    認識できないドライブ名の場合は、空文字が返ります

    ■例

    ・簡単なサンプル

    ①GetDriveNameのサンプル

    VB
    Function GetDriveName_Sample(path As String) As String
    
        Dim obj     As FileSystemObject
        Dim ret     As String
        
        ' オブジェクトを作成
        Set obj = New FileSystemObject
        
        ' GetDriveName
        ret = obj.GetDriveName(path)
        
        ' オブジェクトを破棄
        Set obj = Nothing
        
        ' 結果を返す
        GetDriveName_Sample = ret
        
    End Function
    

    ②-01:呼び出し元関数のサンプル(空の文字列を指定)

    VB
    Sub CallGetDriveName_Sample01()
    
        Dim path    As String
        Dim ret     As String
        
        ' 空文字
        path = ""
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "空文字 ........... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名なし)

    空文字 ........... []
    

    ②-02:呼び出し元関数のサンプル(コロン無しの文字列を指定)

    VB
    Sub CallGetDriveName_Sample02()
    
        Dim path    As String
        Dim ret     As String
        
        ' コロン無
        path = "C"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "コロン無 ......... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名なし)

    コロン無 ......... []
    

    ②-03:呼び出し元関数のサンプル(コロン有りの文字列を指定)

    VB
    Sub CallGetDriveName_Sample03()
    
        Dim path    As String
        Dim ret     As String
        
        ' コロン有
        path = "C:"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "コロン有 ......... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名あり)

    コロン有 ......... [C:]
    

    ②-04:呼び出し元関数のサンプル(コロン全角の文字列を指定)

    VB
    Sub CallGetDriveName_Sample04()
    
        Dim path    As String
        Dim ret     As String
    
        ' コロン全角
        path = "C:"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "コロン全角 ....... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名なし)

    コロン全角 ....... []
    

    ②-05:呼び出し元関数のサンプル(コロン以外の文字列を指定)

    VB
    Sub CallGetDriveName_Sample05()
    
        Dim path    As String
        Dim ret     As String
    
        ' コロン以外
        path = "C\"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "コロン以外 ....... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名なし)

    コロン以外 ....... []
    

    ②-06:呼び出し元関数のサンプル(区切り有りの文字列を指定)

    VB
    Sub CallGetDriveName_Sample06()
    
        Dim path    As String
        Dim ret     As String
    
        ' 区切り有
        path = "C:\"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "区切り有 ......... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名あり)

    区切り有 ......... [C:]
    

    ②-07:呼び出し元関数のサンプル(区切り全角の文字列を指定)

    VB
    Sub CallGetDriveName_Sample07()
    
        Dim path    As String
        Dim ret     As String
    
        ' 区切り全角
        path = "C:¥"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "区切り全角 ....... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名あり)

    区切り全角 ....... [C:]
    

    ②-08:呼び出し元関数のサンプル(スラッシュ有りの文字列を指定)

    VB
    Sub CallGetDriveName_Sample08()
    
        Dim path    As String
        Dim ret     As String
    
        ' スラ有
        path = "C:/"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "スラ有 ........... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名あり)

    スラ有 ........... [C:]
    

    ②-09:呼び出し元関数のサンプル(スラッシュ全角の文字列を指定)

    VB
    Sub CallGetDriveName_Sample09()
    
        Dim path    As String
        Dim ret     As String
    
        ' スラ全角
        path = "C:/"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "スラ全角 ......... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名あり)

    スラ全角 ......... [C:]
    

    ②-10:呼び出し元関数のサンプル(既存フォルダの文字列を指定)

    VB
    Sub CallGetDriveName_Sample10()
    
        Dim path    As String
        Dim ret     As String
    
        ' 既存フォルダ
        path = "C:\Temp"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "既存フォルダ ..... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名あり)

    既存フォルダ ..... [C:]
    

    ②-11:呼び出し元関数のサンプル(既存フォルダと区切り有りの文字列を指定)

    VB
    Sub CallGetDriveName_Sample11()
    
        Dim path    As String
        Dim ret     As String
    
        ' 既存フォルダと区切り有
        path = "C:\Temp\"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "既存と区切り有 ... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名あり)

    既存と区切り有 ... [C:]
    

    ②-12:呼び出し元関数のサンプル(新規フォルダの文字列を指定)

    VB
    Sub CallGetDriveName_Sample12()
    
        Dim path    As String
        Dim ret     As String
    
        ' 新規フォルダ
        path = "C:\Temp2"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "新規フォルダ ..... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名あり)

    新規フォルダ ..... [C:]
    

    ②-13:呼び出し元関数のサンプル(既存ファイルの文字列を指定)

    VB
    Sub CallGetDriveName_Sample13()
    
        Dim path    As String
        Dim ret     As String
    
        ' 既存ファイル
        path = "C:\Temp\temp.txt"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "既存ファイル ..... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名あり)

    既存ファイル ..... [C:]
    

    ②-14:呼び出し元関数のサンプル(新規ファイルの文字列を指定)

    VB
    Sub CallGetDriveName_Sample14()
    
        Dim path    As String
        Dim ret     As String
    
        ' 新規ファイル
        path = "C:\Temp\temp2.txt"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "新規ファイル ..... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名あり)

    新規ファイル ..... [C:]
    

    ②-15:呼び出し元関数のサンプル(新規ドライブの文字列を指定)

    VB
    Sub CallGetDriveName_Sample15()
    
        Dim path    As String
        Dim ret     As String
    
        ' 新規ドライブ
        path = "X:\"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "新規ドライブ ..... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名あり)

    新規ドライブ ..... [X:]
    

    ②-16:呼び出し元関数のサンプル(ひらがなの文字列を指定)

    VB
    Sub CallGetDriveName_Sample16()
    
        Dim path    As String
        Dim ret     As String
    
        ' ひらがな
        path = "あ:\"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "ひらがな ......... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名あり)

    ひらがな ......... [あ:]
    

    ②-17:呼び出し元関数のサンプル(カタカナの文字列を指定)

    VB
    Sub CallGetDriveName_Sample17()
    
        Dim path    As String
        Dim ret     As String
    
        ' カタカナ
        path = "ア:\"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "カタカナ ......... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名あり)

    カタカナ ......... [ア:]
    

    ②-18:呼び出し元関数のサンプル(半角カタカナの文字列を指定)

    VB
    Sub CallGetDriveName_Sample18()
    
        Dim path    As String
        Dim ret     As String
    
        ' 半角カタカナ
        path = "ア:\"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "半角カナ ......... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名あり)

    半角カナ ......... [ア:]
    

    ②-19:呼び出し元関数のサンプル(漢字の文字列を指定)

    VB
    Sub CallGetDriveName_Sample19()
    
        Dim path    As String
        Dim ret     As String
    
        ' 漢字
        path = "亜:\"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "漢字 ............. [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名あり)

    漢字 ............. [亜:]
    

    ②-20:呼び出し元関数のサンプル(数字の文字列を指定)

    VB
    Sub CallGetDriveName_Sample20()
    
        Dim path    As String
        Dim ret     As String
    
        ' 数字
        path = "1:\"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "数字 ............. [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名なし)

    数字 ............. []
    

    ②-21:呼び出し元関数のサンプル(全角数字の文字列を指定)

    VB
    Sub CallGetDriveName_Sample21()
    
        Dim path    As String
        Dim ret     As String
    
        ' 全角数字
        path = "1:\"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "全角数字 ......... [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名なし)

    全角数字 ......... []
    

    ②-22:呼び出し元関数のサンプル(記号の文字列を指定)

    VB
    Sub CallGetDriveName_Sample22()
    
        Dim path    As String
        Dim ret     As String
    
        ' 記号
        path = "+:\"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "記号 ............. [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名なし)

    記号 ............. []
    

    ②-23:呼び出し元関数のサンプル(全角記号の文字列を指定)

    VB
    Sub CallGetDriveName_Sample23()
    
        Dim path    As String
        Dim ret     As String
    
        ' 全角記号
        path = "+:\"
        ' 作成した関数を呼び出す
        ret = GetDriveName_Sample(path)
        Debug.Print "全角記号 ........ [" & ret & "]"
    
    End Sub
    

    出力結果(ドライブ名なし)

    全角記号 ........ []
    

    ③簡略化したGetDriveNameのサンプル

    VB
    Function GetDriveName_Sample2(path As String) As String
    
        ' オブジェクトを作成
        With New FileSystemObject
            ' 指定パスのドライブ名を返す
            GetDriveName_Sample2 = .GetDriveName(path)
        
        End With
        
    End Function
    

    ・説明

    日本人なので、色々な文字をドライブに当てはめてみましたw
    あくまでもドライブ名の文字列として、認識できるもの!?が取得されています
    それがどういうルールなのか、判るようで判りませんねw

    平仮名、片仮名、漢字のドライブ名はありなのね!?w
    もちろん、これらのサンプルのようなドライブ名の付いたドライブが本当にあるのかは、DriveExistsメソッドで確認しないといけませんね!

    半角だからと言って、何でもありってわけじゃない!
    数字や記号は半角も全角も認められないわけですねー

    ・注意点

    • 使い道がわからない!?
    • アルファベットとコロンがあれば取得できる
    • 平仮名、片仮名、漢字もドライブ名として取得できる
    • フォルダパス、ファイルパスでもドライブ名は取得できる
    • フォルダやファイルは既存ではない新規でもドライブ名は取得できる
    • 存在しないドライブ名のパスでもエラーにはならない
    • ドライブ名として認識できない場合は、空文字を返す

    ・その他

    使い道を推測してみます・・

    外部(メールやデータ等)から渡されたフォルダやファイルパスから、存在するドライブ名かを調べるため、
    DriveExistsメソッドの引数に渡す文字列を取得するメソッドなのだと思います!(書いていてよくわからないw)

    というわけで、次はDriveExistsメソッドを調べてみます

    ではでは

  • VBA CreateTextFileの使い方と注意点|書き込み専用を解説

    VBA CreateTextFileの使い方と注意点|書き込み専用を解説

    既存のテキストファイルを開くだけでなく、新規にテキストファイルを作成するようなシーンも考えられるので、CreateTextFileメソッドについても勉強します!

    ■CreateTextFileメソッド

    新規ファイルを作成して、そのTextStreamオブジェクトを返すメソッドです

    既存ファイルはデフォルトで上書きします

    ・構文

    構文は以下の通りです

    object.CreateTextFile (filename, [ overwrite, [ unicode ]])

    objectはFileSystemObjectのオブジェクトです

    ・パラメータ

    メソッドのパラメータは以下の通りです

    • filename … 作成するファイルのパス
    • [overwrite] … 既存ファイルを上書きするかどうか
    • [unicode] … ファイル形式がUnicodeかASCIIか

    filenameには、作成するファイルのパスを設定します(必須項目)

    [overwrite]には、既存のファイルを上書きするかどうかを指定可能です

    True : 上書きする【デフォルト】、False : 上書きしない

    ※既存ファイルのパスで[overwrite]をFalseにするとエラーが発生する

    [unicode]には、作成するファイルがUnicodeかASCIIかを指定可能です

    True : Unicode、False : ASCII【デフォルト】

    ・戻り値

    メソッドの戻り値は以下の通りです

    • TextStreamオブジェクト

    どうやらこのTextStreamオブジェクトは、書き込み専用のようです!(?)

    既存ファイルが読み取り専用だとした場合、上書きできないのでエラーになります

    上書き可能な状態の場合は、空の状態で作成されるので、読み取りできるものがなく、書き込みしか受け付けない状態です!

    ■例

    ・簡単なサンプル

    ①-1:CreateTextFileの参照設定を使用したサンプル

    VB
    Sub CreateTextFile_Sample(filename As String, oText As TextStream)
    
        Dim obj     As FileSystemObject
        
        ' オブジェクトを作成
        Set obj = New FileSystemObject
        
        ' TextStreamオブジェクトを取得
        Set oText = obj.CreateTextFile(filename, True, False)
        
        ' オブジェクトを破棄
        Set obj = Nothing
            
    End Sub
    

    FileSystemObjectのScriptingライブラリを参照設定しておけば、上記サンプルのように、FileSystemObjectオブジェクトもTextStreamオブジェクトも変数や引数の型で指定できます

    ①-2:CreateTextFileの実行時バインディングのサンプル

    VB
    Sub CreateTextFile_Sample2(filename As String, oText As Object)
    
        Dim obj     As Object
        
        ' オブジェクトを作成
        Set obj = CreateObject("Scripting.FileSystemObject")
        
        ' TextStreamオブジェクトを取得
        Set oText = obj.CreateTextFile(filename, True, False)
        
        ' オブジェクトを破棄
        Set obj = Nothing
            
    End Sub
    

    実行時バインディングを使用した書き方は①-2のようになりますね!
    上記のように、FileSystemObjectオブジェクトを作成して、そのCreateTextFileメソッドでTextStreamオブジェクトを取得します!

    ①-3:TextStreamを実行時バインディングで呼び出そうとしたサンプル

    VB
    Sub TextStream_Sample()
    
        Dim obj     As Object
        
        ' オブジェクトを作成(エラーになる)
        Set obj = CreateObject("Scripting.TextStream")
        
        ' オブジェクトを破棄
        Set obj = Nothing
            
    End Sub
    

    TextStreamもScriptingライブラリに含まれていますけど、①-3のように書いてもTextStreamオブジェクトは作成できませんのでご注意をー

    ②-1:呼び出し元関数の(エラーになる)読み取りサンプル

    VB
    Sub CallCreateTextFile_Sample1()
        Dim oText       As TextStream
        Dim filename    As String
        
        ' CreateTextFileファイルパス
        filename = "E:\VBA\Sample001\Sample.txt"
        
        ' 作成した関数を呼び出す
        Call CreateTextFile_Sample(filename, oText)
        
        With oText
            ' ファイルの最後まで読み込む(エラーになる)
            Do Until .AtEndOfStream
                
                ' 一行(改行コードまで)を読み込む
                Debug.Print .ReadLine
                
                ' 行番号を返す
                Debug.Print .Line
                
            Loop
            
            ' フィルを閉じる
            .Close
            
        End With
        
        ' TextStreamオブジェクトを破棄
        Set oText = Nothing
    
    End Sub
    

    CreateTextFileメソッドは空のファイルを作成しますので、それを読み込もうとして、ReadLineメソッドでは何も取得できません

    ②-1のようにAtEndOfStreamプロパティを参照した時点で「ファイルモードが不正です」とエラーになりますので、CreateTextFileメソッドは書き込み専用のモードであることがわかります
    そのため、当然、ReadLineメソッドをも同じ「ファイルモードが不正です」のエラーになります

    ②-2:呼び出し元関数の(エラーにならない)書き込みの参照設定でのサンプル

    VB
    Sub CallCreateTextFile_Sample2()
        Dim oText       As TextStream
        Dim filename    As String
        
        ' CreateTextFileファイルパス
        filename = "E:\VBA\Sample001\Sample.txt"
        
        ' 作成した関数を呼び出す
        Call CreateTextFile_Sample(filename, oText)
        
        With oText
            
            ' 一行(改行コードまで)を書き込む
            Call .WriteLine("AAA")
            
            ' 空行を書き込む
            Call .WriteBlankLines(1)
            
            ' 行番号を返す
            Debug.Print .Line
            
            ' フィルを閉じる
            .Close
            
        End With
        
        ' TextStreamオブジェクトを破棄
        Set oText = Nothing
    
    End Sub
    

    ②-2はCreateTextFileメソッドで作成したTextStreamオブジェクトに対して、書き込みを行うサンプルです

    1. WriteLineメソッドで改行コードを付加して「AAA」を書き込む
    2. WriteBlankLinesメソッドで指定した行数の空行を書き込む
    3. Lineプロパティを参照して行番号を取得
    4. Closeメソッドでファイルを閉じる

    この処理で、ファイルは以下の内容になります

    Lineプロパティの結果は以下のように[EOF]の行番号である「3」が返ります

    ②-3:呼び出し元関数の(エラーにならない)書き込みの実行時バインディングの関数を呼び出すサンプル

    VB
    Sub CallCreateTextFile_Sample2()
        Dim oText       As Object
        Dim filename    As String
        
        ' CreateTextFileファイルパス
        filename = "E:\VBA\Sample001\Sample.txt"
        
        ' 作成した関数を呼び出す
        Call CreateTextFile_Sample2(filename, oText)
        
        With oText
            
            ' 一行(改行コードまで)を書き込む
            Call .WriteLine("AAA")
            
            ' 空行を書き込む
            Call .WriteBlankLines(1)
            
            ' 行番号を返す
            Debug.Print .Line
            
            ' フィルを閉じる
            .Close
            
        End With
        
        ' TextStreamオブジェクトを破棄
        Set oText = Nothing
    
    End Sub
    

    ②-2と②-3での違いは以下の2点だけですね

    1. 呼び出す関数名が違っている
    2. TextStreamオブジェクトの宣言

    呼び出す関数名の違いは、都合上なので、実質は「TextStreamオブジェクトの宣言」のみです

    ③:簡略化したCreateTextFileのサンプル

    VB
    Sub CreateTextFile_Sample2(ByVal filename As String, ByRef oText As TextStream)
    
        ' オブジェクトを作成
        With New FileSystemObject
            ' TextStreamオブジェクトを返す
            Set oText = .CreateTextFile(filename)
        
        End With
        
    End Sub
    

    ・説明

    サンプルが多かったので、説明は各サンプルの後ろに付けましたので、ここでは特に書くことがなくなってしまいました

    ③はいつものサンプルです
    実行時バインディングを使用したサンプルは簡略化という点では向いていないので省いていますw

    ・注意点

    • 既存ファイルは上書き指定できる
    • 読み取り専用ファイルを上書き指定するとエラーになる
    • 上書き指定すると新規ファイルとなり、既存テキストは削除される
    • 取得したTextStreamオブジェクトは書き込みしかできない
    • 存在しないファイルを指定すれば新規ファイルを作成します
    • 存在しない親階層を指定するとエラーになります
    • 作成したファイルはTextStreamオブジェクトのCloseメソッドで閉じます
    • 作成するファイルのファイル形式(エンコーディング)によって改行コードは異なる

    ・その他

    同じTextStreamオブジェクトを返すOpenTextFileメソッドと比較してみる

    メソッド対象ファイル入出力ファイル形式
    CreateTextFile新規ファイル

    既存は「上書きする」がデフォルト

    書き込み専用

    (変更不可)

    True/Falseで指定
    OpenTextFile既存ファイル

    新規は「作成しない」がデフォルト

    読み取り専用

    (変更可能)

    Tristate列挙型で指定

    とまぁ、意外と色々違うんですね!

    もう少し、FileSystemObjectのメソッドを色々と調べておきたいのだけど、サンプルで色々試したので、次こそはTextStreamオブジェクトについても詳しく記載しないとね!w

    ではでは

  • VBA CreateFolderで多階層フォルダ作成!再帰的サンプル

    VBA CreateFolderで多階層フォルダ作成!再帰的サンプル

    ファイル出力を行う際に、フォルダを作る処理が必要になりました

    そのため、CreateFolderメソッドについて調べてみます

    MkDirメソッド同様に、親フォルダがない場合はエラーになってしまいますので、再帰的にフォルダを作成するサンプルなどを作成します

    ■CreateFolderメソッド

    フォルダを作成するメソッドですね

    ・構文

    構文は以下の通りです

    object.CreateFolder (foldername)

    objectはFileSystemObjectのオブジェクトです

    ・パラメータ

    メソッドのパラメータは以下の通りです

    • foldername … 作成するフォルダのパス

    作成するフォルダのパスを設定しますが、最後の文字はフォルダの区切り文字でなくても、作成するフォルダを識別した文字列として処理されます

    ・戻り値

    メソッドの戻り値は以下の通りです

    • 戻り値 … Folderオブジェクト

    作成したフォルダのFolderオブジェクトを戻り値として返します

    ■例

    ・簡単なサンプル

    ①CreateFolderのサンプル

    VB
    Sub CreateFolder_Sample(foldername As String, oFolder As Folder)
    
        Dim obj     As FileSystemObject
       
        ' オブジェクトを作成
        Set obj = New FileSystemObject
        
        ' CreateFolder
        Set folder = obj.CreateFolder(foldername)
        
        ' オブジェクトを破棄
        Set obj = Nothing
        
    End Sub
    

    ②呼び出し元関数のサンプル

    VB
    Sub CallCreateFolder_Sample()
    
        Dim foldername      As String
        Dim oFolder         As Folder
        
        ' CreateFolderファイルパス
        foldername = "E:\VBA\Sample003\Sample"
        
        ' 作成した関数を呼び出す
        Call CreateFolder_Sample(foldername, oFolder)
    
        Debug.Print oFolder.Name
        
        ' Folderオブジェクトを破棄
        Set oFolder = Nothing
    
    End Sub
    

    ③簡略化したCreateFolderのサンプル

    VB
    Sub CreateFolder_Sample2(ByVal foldername As String, ByRef oFolder As Folder)
    
        ' オブジェクトを作成
        With New FileSystemObject
            ' 作成したフォルダのFolderオブジェクトを返す
            Set oFolder = .CreateFolder(foldername)
        
        End With
        
    End Sub
    

    ・説明

    サンプルはいつも通りのFileSystemObjectオブジェクトを作成するサンプルと、簡略化したサンプルです

    ただ、戻り値がオブジェクトのため、関数の引数で受け取るようにしています

    その経緯については、別のメソッドのところで、書いていますが、オブジェクトは関数の戻り値ではなく、引数で返すことをお勧めしています

    ・再帰的に繰り返すサンプル

    最初にも書きましたけど、CreateFolderメソッドはフォルダを作るメソッドですが、親フォルダがない場合は、エラーになってしまいます
    その場合は、以下のサンプルのように親フォルダを確認しながら作成していきます

    ④再帰的に呼び出して存在しない親階層フォルダを作成するサンプル

    VB
    Sub CreateFolderRecursion(foldername As String)
        Dim parent      As String   ' 親階層
    
        ' オブジェクトを作成
        With New FileSystemObject
            ' 親階層を取得
            parent = .GetParentFolderName(foldername)
            
            ' 親階層フォルダがない場合
            If (.FolderExists(parent) = False) Then
                ' 再帰呼び出し
                Call CreateFolderRecursion(parent)
                
            End If
            
            ' 指定階層フォルダがない場合
            If (.FolderExists(foldername) = False) Then
                ' フォルダ作成
                Call .CreateFolder(foldername)
                
            End If
    
        End With
    
    End Sub
    

    ・大量フォルダを作るサンプル

    1つのフォルダ内に、番号のフォルダを大量に作る場合がある場合、

    ①や③の関数を呼び出していては、オーバーヘッドが多くなり無駄ができます

    そのため、以下のサンプルのように、FileSystemObjectの作成を1回で済ませ、CreateFolderメソッドを等も呼ぶようにします
    ⑤大量フォルダを作成するサンプル

    VB
    Sub CreateFolderMassive(ByVal foldername As String, count As Long)
        Dim sFolder     As String
        Dim idx         As Long
        
        ' オブジェクトを作成
        With New FileSystemObject
            ' countまでループ
            For idx = 1 To count
                ' idxの番号でフォルダを作成する
                sFolder = .BuildPath(foldername, idx)
                ' foldername配下にフォルダを作成
                Call .CreateFolder(sFolder)
                
            Next idx
        
        End With
        
    End Sub
    

    ・注意点

    • 親フォルダがない場合はエラーになるので、再帰的な作成が必要
    • 関数化して呼び出す場合は、戻り値のオブジェクトは引数で受け渡す
    • 指定するフォルダパスは区切り文字でなくてもよい
    • 呼び出し元でオブジェクトを宣言して、使用し終わったら破棄する

    ・その他

    システムによっては、フォルダが色々な意味を成す場合があります

    そのため、フォルダを作成することは、大事なのです

    同じような注意点はなるべく書かないようにしていますので、他の記事も参考にしてください

    ではでは

  • VBA FolderExistsでエラー回避!フォルダ存在チェックの書き方

    VBA FolderExistsでエラー回避!フォルダ存在チェックの書き方

    Excel VBAを使用した場合、ExcelファイルのOpenはWorkbooksオブジェクトで行うので、FileSystemObjectでファイル作成を行う場合、ファイルだけでなくフォルダの存在確認を行うFolderExistsメソッドも必要ですね!

    ■FolderExistsメソッド

    フォルダの存在を確認するメソッドです

    ・構文

    構文は以下の通りです

    object.FolderExists(folderspec)

    objectはFileSystemObjectのオブジェクトです

    ・パラメータ

    メソッドのパラメータは以下の通りです

    • folderspec … 存在を確認するフォルダパス

    存在確認を行うフォルダのフルパスを指定します(相対パス、もしくは絶対パスにて指定可能)

    ・戻り値

    メソッドの戻り値は以下の通りです

    • True … フォルダが存在する
    • False … フォルダが存在しない

    パラメータで指定したフォルダが存在する場合はTrueを返し、存在しない場合はFalseを返します

    ■例

    ・簡単なサンプル

    ‘ ①FolderExistsのサンプル

    VB
    Function FolderExists_Sample(folderspec As String) As Boolean
    
        Dim obj     As FileSystemObject
        Dim ret     As Boolean
        
        ' オブジェクトを作成
        Set obj = New FileSystemObject
        
        ' フォルダの存在確認
        ret = obj.FolderExists(folderspec)
        
        ' オブジェクトを破棄
        Set obj = Nothing
        
        ' 結果を返す
        FolderExists_Sample = ret
        
    End Function
    

    ‘ ②呼び出し元関数のサンプル

    VB
    Sub CallFolderExists_Sample()
    
        Dim folderspec      As String
        
        ' 調べたいフォルダパス
        folderspec = "E:\VBA\Sample.003\"
        
        ' 作成した関数を呼び出す
        If (FolderExists_Sample(folderspec) = True) Then
            ' 戻り値がTrueなら存在する
            Debug.Print "フォルダは存在します"
        
        Else
            ' 戻り値がTrue以外(False)なら存在しない
            Debug.Print "フォルダは存在しません"
        
        End If
    
    End Sub
    

    ‘ ③簡略化したFolderExistsのサンプル

    VB
    Function FolderExists_Sample2(folderspec As String) As Boolean
    
        ' オブジェクトを作成
        With New FileSystemObject
            ' フォルダの存在確認結果を返す
            FolderExists_Sample2 = .FolderExists(folderspec)
        
        End With
        
    End Function
    

    ・説明

    FileSystemObject型の変数でオブジェクトを作成しないといけませんので、関数化して呼び出すのが便利です

    ステップをきっちりと書きたい人は、①の方式で書いた上で、エラートラップや以下の引数チェックをやるのが良いかも知れません

    • 空文字ではないか?
    • フォルダパス形式か?

    簡略化したい場合は、③のようにすればよいでしょう

    ②は呼び出し元です

    ①でも③でもどちらを呼んでも同じ結果になります!

    ・注意点

    根本的なことなので個々のメソッドで書く必要はない内容ではありますが、多くのメソッドでは書かないようにするので、このあたり頻繁に使いそうなメソッドで書いておこうと思います

    • FileSystemObjectのオブジェクトを作成する場合は、NewでSetしてください!
    • 特に③を使用する場合、Newを書き忘れてもVBA的にはコーディングエラーではなく、実行時エラーになりますのでご注意ください
    • エラートラップやパラメータチェックについては、コーディング方針(最下位のメソッドでチェックするか、上位でチェックするか等)に従ってください

    ・その他

    関数の呼び出し毎にFileSystemObjectのオブジェクトを作成したくない人は、標準モジュールではなくクラスモジュールでクラス化してください

    • Class_InitializeイベントでNew FileSystemObject
    • Class_TerminateイベントでNothing

    ではでは

  • VBA CopyFileの使い方とエラー対策|上書きできない原因も解説

    VBA CopyFileの使い方とエラー対策|上書きできない原因も解説

    ファイルのコピーって、必要ですよね!というわけで、コピーしちゃいますw

    ■CopyFileメソッド

    そのままですけど、ファイルをコピーするためのメソッドです

    ワイルドカード文字「*」を使用して複数ファイルのコピーも可能です

    フォルダのコピーは別メソッドなので、それは別で紹介します!

    ・構文

    構文は以下の通りです

    object.CopyFile source, destination, [ overwrite ]

    objectはFileSystemObjectのオブジェクトです

    ・パラメータ

    メソッドのパラメータは以下の通りです

    • source … コピーするファイルのパス
    • destination … コピー先のフォルダやファイルのパス
    • [overwrite] … 既存のファイルを上書きするかどうか

    sourceには、コピーするファイルのパスを指定、ワイルドカード文字列をしようすることで複数ファイルを指定します(必須項目)

    destinationには、コピー先フォルダやファイルを指定できますが、ワイルドカード文字列は使用不可です(必須項目)

    [overwrite]には、コピー先フォルダにコピー元のファイルと同名ファイルがある場合に、上書きするかを設定します

    True : 上書きする【デフォルト】、False : 上書きしない

    ・戻り値

    メソッドの戻り値は以下の通りです

    • なし

    コピーが成功したかどうかを戻り値で受け取りたいところですけど、ないんですってー!

    ■例

    ・簡単なサンプル

    ①CopyFileのサンプル

    VB
    Function CopyFile_Sample(source As String, destination As String, Optional overwrite As Boolean = True) As Boolean
    On Error Resume Next
        Dim obj     As FileSystemObject
        Dim ret     As Boolean
    	
        ' オブジェクトを作成
        Set obj = New FileSystemObject
    	
        Err.Clear
    	
        ' CopyFileの呼び出し
        Call obj.CopyFile(source, destination, overwrite)
    	
    Debug.Print Err.Number, Err.Description
    
        ' オブジェクトを破棄
        Set obj = Nothing
    	
        ' 結果を返す
        CopyFile_Sample = ret
    	
    End Function
    

    ②呼び出し元関数のサンプル

    VB
    Sub CallCopyFile_Sample()
    
        Dim source          As String
        Dim destination     As String
        
        ' コピーするファイルパス
        source = "E:\VBA\Sample001\Sample.txt"
        
        ' コピー先フォルダをパスの区切り文字終わりで指定
        destination = "E:\VBA\Sample002\"
        ' 作成した関数を呼び出す・・・(1)
        Call CopyFile_Sample(source, destination)
        
        ' コピー先を既存ファイルに指定
        destination = "E:\VBA\Sample002\Sample.txt"
        ' 作成した関数を呼び出す・・・(2)
        Call CopyFile_Sample(source, destination)
        
        ' コピー先を存在しないファイルに指定
        destination = "E:\VBA\Sample002\SampleCopy.txt"
        ' 作成した関数を呼び出す・・・(3)
        Call CopyFile_Sample(source, destination)
        
        ' コピーするファイルパス
        source = "E:\VBA\Sample001\Sample.txt"
        ' コピー先を既存ファイル(読み取り専用)に指定
        destination = "E:\VBA\Sample002\ReadOnly.txt"
        ' 作成した関数を呼び出す・・・(4)
        Call CopyFile_Sample(source, destination)
        
        ' コピー先フォルダをパスの区切り文字終わらず既存フォルダを指定
        destination = "E:\VBA\Sample002"
        ' 作成した関数を呼び出す・・・(5)
        Call CopyFile_Sample(source, destination)
        
        ' コピー先フォルダを存在しないパスの区切り文字終わらず指定
        destination = "E:\VBA\Sample003"
        ' 作成した関数を呼び出す・・・(6)
        Call CopyFile_Sample(source, destination)
        
        
        ' コピーするファイルパス(ワイルドカード文字列を使用)
        source = "E:\VBA\Sample001\*.txt"
        ' コピー先フォルダをパスの区切り文字終わりで指定
        destination = "E:\VBA\Sample002\"
        ' 作成した関数を呼び出す・・・(7)
        Call CopyFile_Sample(source, destination)
        
        ' コピーするファイルパス(ワイルドカード文字列を使用)
        source = "E:\VBA\Sample001\Sample.*"
        ' コピー先フォルダをパスの区切り文字終わりで指定
        destination = "E:\VBA\Sample002\"
        ' 作成した関数を呼び出す・・・(8)
        Call CopyFile_Sample(source, destination)
        
        ' コピーするファイルパス(ワイルドカード文字列をフォルダに使用)
        source = "E:\VBA\Sample*\Sample.csv"
        ' コピー先フォルダをパスの区切り文字終わりで指定
        destination = "E:\VBA\Sample002\"
        ' 作成した関数を呼び出す・・・(9)
        Call CopyFile_Sample(source, destination)
        
        ' コピーするファイルパス
        source = "E:\VBA\Sample001\Sample.txt"
        ' コピー先フォルダ(ワイルドカード文字列を使用)
        destination = "E:\VBA\Sample002\*.txt"
        ' 作成した関数を呼び出す・・・(10)
        Call CopyFile_Sample(source, destination)
        
        ' コピーするファイルパス(ワイルドカード文字列を使用して存在しないファイル)
        source = "E:\VBA\Sample001\ZZZ*.txt"
        ' コピー先フォルダをパスの区切り文字終わりで指定
        destination = "E:\VBA\Sample002\"
        ' 作成した関数を呼び出す・・・(11)
        Call CopyFile_Sample(source, destination)
        
        
        ' コピーするファイルパス
        source = "E:\VBA\Sample001\Sample.txt"
        ' コピー先を既存ファイルに指定
        destination = "E:\VBA\Sample002\Sample.txt"
        ' 作成した関数を上書きしないで呼び出す・・・(12)
        Call CopyFile_Sample(source, destination, False)
        
        ' コピーするファイルパス
        source = "E:\VBA\Sample001\Sample.txt"
        ' コピー先を既存ファイル(読み取り専用)に指定
        destination = "E:\VBA\Sample002\ReadOnly.txt"
        ' 作成した関数を上書きしないで呼び出す・・・(13)
        Call CopyFile_Sample(source, destination, False)
        
        ' コピーするファイルパス(ワイルドカード文字列を使用)
        source = "E:\VBA\Sample001\*.csv"
        ' コピー先フォルダをパスの区切り文字終わりで指定
        destination = "E:\VBA\Sample002\"
        ' 作成した関数を上書きしないで呼び出す・・・(14)
        Call CopyFile_Sample(source, destination, False)
        
    End Sub
    

    ③簡略化したCopyFileのサンプル

    VB
    Function CopyFile_Sample2(source As String, destination As String) As Boolean
        ' オブジェクトを作成
        With New FileSystemObject
            ' ファイルコピー
            Call .CopyFile(source, destination)
    		
        End With
    	
    End Function
    

    ・説明

    呼び出し元関数のサンプルにて、想定できそうなパターンを網羅したつもりです!

    以下のような階層にファイルが存在しているとして、サンプルを実行します

    VB
    E:.
    ├─Sample001
    │      Sample.csv
    │      Sample.txt
    │      Sample1.csv
    │      Sample1.txt
    
    └─Sample002
            ReadOnly.txt
            Sample.txt
    

    実行した結果は以下のようにイミディエイトウィンドウに表示されます

    (1)~(3)と(6)~(8)が正常終了ということがわかります!

    読み取り専用ファイルに対する動作は、(4)と(13)のように[overwrite]によってエラーが異なります

    ・・(4)と(13)かぁー不思議と縁起の悪い番号に割り振られたw

    VB
     0            
     0            
     0            
     70           書き込みできません。
     70           書き込みできません。
     0            
     0            
     0            
     5            プロシージャの呼び出し、または引数が不正です。
     5            プロシージャの呼び出し、または引数が不正です。
     53           ファイルが見つかりません。
     58           既に同名のファイルが存在しています。
     58           既に同名のファイルが存在しています。
     58           既に同名のファイルが存在しています。
    

    実行結果後の階層はこうなります!

    (6)ではフォルダではなく、ファイルが作成されたことが確認できますね

    (14)では”Sample.csv”の上書きコピーが許可されずエラーとなったため、”Sample1.csv”はコピーされなかったことがわかりますね

    VB
    E:.
    │  Sample003
    
    ├─Sample001
    │      Sample.csv
    │      Sample.txt
    │      Sample1.csv
    │      Sample1.txt
    
    └─Sample002
            ReadOnly.txt
            Sample.csv
            Sample.txt
            Sample1.txt
            SampleCopy.txt
    

    ・注意点

    • コピー先ファイルに上書きを許可しても、コピー先ファイルが読み取り専用の場合は、ファイルコピーがエラーになる
    • コピー先の指定にはワイルドカード文字列は指定できない
    • コピー元ファイルのワイルドカード文字列は、ファイル名や拡張子(最後のパス コンポーネント)にのみ使用可能
    • コピー先はパスの区切り文字で終わっている場合に、既存フォルダと見なされる
    • コピー先パスを区切り文字で終えずに既存フォルダを指定した場合は、書き込みエラーになる
    • 複数ファイルのコピー時にエラーが発生したら、続きはコピーされない

    ・その他

    TextStreamオブジェクトについて書くつもりでしたが、ファイルのコピーが意外と大事だったので、先に調べました!

    あと、他のメソッドで記載したような注意点は、共通的なものでも何度も書かないことにしますので、他のメソッドも是非確認してくださいね!

    ではでは

  • OpenTextFileの使い方とサンプル|VBAでテキスト読み込み

    OpenTextFileの使い方とサンプル|VBAでテキスト読み込み

    シート一覧を作ろうと思ってたんですが、仕事でCSVファイルを開く処理を作らないといけなくなったので、調べたことを書いておきます!w

    ■OpenTextFileメソッド

    テキストファイルを開いて、そのファイルの読み書きに使用できるTextStraemオブジェクトを取得するメソッドです

    ・構文

    構文は以下の通りです

    object.OpenTextFile (filename, [ iomode, [ create, [ format ]]])

    objectはFileSystemObjectのオブジェクトです

    ・パラメータ

    メソッドのパラメータは以下の通りです

    • filename … 開くファイルのパス
    • [iomode] … 入出力モード
    • [create] … ファイルを新規作成するか
    • [format] … ファイルの形式

    filenameには、開くファイルのパスを設定します(必須項目)

    [iomode]には、開くファイルの入出力モードを下記の「IOMode列挙型」から指定可能です

    [create]には、指定したファイルが存在しない場合、新規作成するかどうかを指定可能です

    True : 新規作成する、False : 新規作成しない【デフォルト】

    [format]には、ファイルの形式を下記の「TRristate列挙型」から指定可能です

    – IOMode列挙型​

    パラメータで指定できる項目は以下の通りです

    • 1:ForReading(読み取り専用)【デフォルト】
    • 2:ForWriting(上書き書き込み)
    • 8:ForApending(追加書き込み)

    編集しない場合や他からのアクセスが考えられる場合は「ForReading」で開く

    元のファイルの内容を気にしない場合は「ForWriting」で開く

    元のファイルの内容の行末尾に追加する場合は「ForApending」で開く

    – Tristate列挙型

    パラメータで指定できる項目は以下の通りです

    • 0:TristateFalse(ASCII[Shift-JIS])【デフォルト】
    • -1:TristateTrue(Unicode[UTF-16])
    • -2:TristateUseDefault(システムのデフォルト設定)
    • -2:TristateMixed(混在)

    ASCII(Shift-JIS)ファイルとする場合は「TristateFalse」で開く

    Unicode(UTF-16)ファイルとする場合は「TristateTrue」で開く

    システムのデフォルト設定とする場合は「TristateUseDefault」で開く

    ※混在は「システムのデフォルト設定」と同じ値なので、「TristateMixed」でも「TristateUseDefault」と同じです

    てか、省略したら「システムのデフォルト設定」ではなく、「ASCII」なんですね!w

    ・戻り値

    メソッドの戻り値は以下の通りです

    • TextStreamオブジェクト

    指定したファイルのTextStreamオブジェクトなので、変数にSetしてください

    ■例

    ・簡単なサンプル

    ①OpenTextFileのサンプル

    VB
    Sub OpenTextFile_Sample(fileName As String, oText As TextStream)
        Dim obj     As FileSystemObject
        ' オブジェクトを作成
        Set obj = New FileSystemObject
        ' TextStreamオブジェクトを取得
        Set oText = obj.OpenTextFile(fileName, ForReading, False, TristateFalse)
        ' オブジェクトを破棄
        Set obj = Nothing
    End Sub
    

    ②呼び出し元関数のサンプル

    VB
    Sub CallOpenTextFile_Sample()
        Dim oText       As TextStream
        Dim fileName    As String
        ' オブジェクトを取得したいファイルパス
        fileName = "E:VBASample001Sample.txt"
        ' 作成した関数を呼び出す
        Call OpenTextFile_Sample(fileName, oText)
        With oText
            ' ファイルの最後まで読み込む
            Do Until .AtEndOfStream
                ' 一行(改行コードまで)を読み込む
                Debug.Print .ReadLine
                ' 行番号を返す
                Debug.Print .Line
            Loop
            ' フィルを閉じる
            .Close
        End With
        ' TextStreamオブジェクトを破棄
        Set oText = Nothing
    End Sub
    

    ③簡略化したOpenTextFileのサンプル

    VB
    Sub OpenTextFile_Sample2(ByVal fileName As String, ByRef oText As TextStream)
        ' オブジェクトを作成
        With New FileSystemObject
            ' TextStreamオブジェクトを返す
            Set oText = .OpenTextFile(fileName)
        End With
    End Sub
    

    ・説明

    Callと簡略化だけでよくないか?と思い始めましたが・・

    口を酸っぱくするくらいに言いますが、FileSystemObjectを使用する場合は、関数化して呼び出すようにして、エラートラップを施してください

    呼び出し元の関数内に、FileSystemObjectが出てこないのが理想です!

    取得したTextStreamオブジェクトの使い方については、別途記事にしていきます

    ここでは簡単に、読み取り専用で開いて、ファイルの最後まで1行毎に読み取る処理にしています

    ・注意点

    • 指定したファイルが存在しても読み取り専用や排他状態だった場合、IOModeで「書き込み」を指定するとエラーになる
    • 指定したファイルが読み取り専用かどうかは、FileオブジェクトのAttributesプロパティで調べることができる
    •  排他状態は困難な(Attributesプロパティでわからない)ので、読み取り専用で開こう!
    •  書き込みたいなら、新規ファイルを作成しよう!w
    • 指定したファイルがなければ、新規作成ができるらいしいが、親フォルダや階層がなかったら!?
    • オブジェクトを返すメソッドを関数化するときは、引数で受け渡す
    • 引数で受け取って関数内でSetしたオブジェクトは、呼び出し側でNothingする

    ・その他

    OpenTextFileメソッドに限ったことではないですが・・

    複数のオブジェクトを1つの関数内で扱うと破棄する処理が大変になります

    1オブジェクト1関数で対応するようにしましょ!

    ※個人的な見解ですが、汎用性が高いソースコードになると思います

    TextStreamオブジェクトが出てきたので、読み書きのサンプルを紹介がてら、次回は、TextStreamオブジェクトについて書いてみます

    ではでは

  • GetFileの使い方と実用サンプル|VBAでファイル情報を取得

    GetFileの使い方と実用サンプル|VBAでファイル情報を取得

    ファイル一覧を作成した時は、GetFolderメソッドで、FilesプロパティをFor Each…Nextステートメントで回して、Fileオブジェクトを取得しました

    主なメソッドやプロパティはそこで記載したので、もうお判りでしょう!?w

    そのFileオブジェクトを取得するメソッドについてです!

    ■GetFileメソッド

    パラメータで指定したファイルのFileオブジェクトを取得します

    ・構文

    構文は以下の通りです

    object.GetFile(filespec)

    objectはFileSystemObjectのオブジェクトです

    ・パラメータ

    メソッドのパラメータは以下の通りです

    • filespec … オブジェクトを取得したいファイルのパス

    ファイルへのパス(絶対パスもしくは相対パス)を指定します

    存在しないファイルを指定した場合は、エラーが発生します

    ・戻り値

    メソッドの戻り値は以下の通りです

    • Fileオブジェクト

    指定したファイルのFileオブジェクトが戻り値として取得できますので、変数にSetしてください

    ■例

    ・簡単なサンプル?

    ①GetFileのサンプル

    VB
    Function GetFile_Sample1(filespec As String) As File
        Dim obj     As FileSystemObject
        Dim oFile   As File
    	
        ' オブジェクトを作成
        Set obj = New FileSystemObject
    	
        ' Fileオブジェクトを取得
        Set oFile = obj.GetFile(filespec)
    	
        ' オブジェクトを破棄
        Set obj = Nothing
    	
        ' 結果を返す
        Set GetFile_Sample1 = oFile
    	
        ' オブジェクトを破棄
        Set oFile = Nothing
    	
    End Function
    

    ②呼び出し元関数のサンプル

    VB
    Sub CallGetFile_Sample1()
        Dim filespec    As String
        Dim oFile       As File
    	
        ' オブジェクトを取得したいファイルパス
        filespec = "E:\VBA\Sample001\Sample.txt"
    	
        ' 作成した関数を呼び出す
        Set oFile = GetFile_Sample1(filespec)
    	
    	' ファイル名を出力
        Debug.Print oFile.Name
    	
    	' Fileオブジェクトを破棄
        Set oFile = Nothing
    	
    End Sub
    

    ③簡略化したGetFileのサンプル

    VB
    Function GetFile_Sample2(filespec As String) As File
        ' オブジェクトを作成
        With New FileSystemObject
            ' Fileオブジェクトを返す
            Set GetFile_Sample2 = .GetFile(filespec)
    		
        End With
    	
    End Function
    

    ・説明

    FileSystemObjectを使おうが、別の何かを使おうが、とにかく関数化しておくことをお勧めします!

    戻り値がオブジェクトなので、FileSystemObjectとFileの両方のオブジェクトを変数で作成しようとすると、①のように大変回りくどいことになってしまいますw

    そのため、シンプルに③のようにするのが良いかと思います

    ・より良いサンプル

    それでも気持ち悪いから嫌だ!という方は、こちらの「より良いサンプル」をどうぞ!w
    ④GetFileのより良いサンプル

    VB
    Sub GetFile_Sample3(ByVal filespec As String, ByRef oFile As File)
        Dim obj     As FileSystemObject
    	
        ' オブジェクトを作成
        Set obj = New FileSystemObject
    	
        ' Fileオブジェクトを取得
        Set oFile = obj.GetFile(filespec)
    	
        ' オブジェクトを破棄
        Set obj = Nothing
    	
    End Sub
    

    ⑤呼び出し元関数のサンプル2

    VB
    Sub CallGetFile_Sample2()
        Dim filespec    As String
        Dim oFile       As File
    	
        ' オブジェクトを取得したいファイルパス
        filespec = "E:\VBA\Sample001\Sample.txt"
    	
        ' 作成した関数を呼び出す
        Call GetFile_Sample3(filespec, oFile)
    	
    	' ファイル名を出力
        Debug.Print oFile.Name
    	
        ' Fileオブジェクトを破棄
        Set oFile = Nothing
    	
    End Sub
    

    ⑥簡略化したGetFileのより良いサンプル

    VB
    Sub GetFile_Sample4(ByVal filespec As String, ByRef oFile As File)
        ' オブジェクトを作成
        With New FileSystemObject
            ' Fileオブジェクトを返す
            Set oFile = .GetFile(filespec)
    		
        End With
    	
    End Sub
    

    ・更により良くする

    更により良い関数化を行う場合はエラートラップを行って、その結果(エラーが起きたかどうか)を「GetFile_Sample」の戻り値で返す!
    そうすると、呼び出し側は引数で受け取ったオブジェクトが正しいかどうかを関数の戻り値で判断できるので、「oFile」を参照して判断する必要がなくなりますね!

    「If Not (oFile Is Nothing) Then … End If」で処理してもいいですが、「否定の否定」的な感じになるので「If (戻り値 = True) Then … End If」が良いです
    「If (oFile Is Nothing) Then … Else … End If」でもありですけどね!
    ※この「Is Nothing」は「If ((oFile Is Nothing) = True) Then」のように見えるので、便利ですけどあまり好きじゃないですw

    えーーーっと、もうサンプルは書きませんよw

    ・注意点

    • 指定するファイルパスは存在しないとエラーになる
    • FileExistsメソッドでファイルの存在確認をしておく
    • GetFileメソッドのエラー有無でファイルの存在確認としない
    • オブジェクトを返すメソッドを関数化するときは、引数で受け渡す
    • 関数内変数にSetしたオブジェクトは、関数内でNothingする
    • 引数で受け取って関数内でSetしたオブジェクトは、呼び出し側でNothingする
    • 関数内で起きたエラーは、呼び出し側に通知すべき

    ・その他

    Excel VBAでも関数の引数には、ByVal(値渡し)とByRef(参照渡し)があります
    趣味の世界かも知れませんが、本来は全ての関数の全ての引数で、正しく宣言するべきです!
    ※でもーーー、面倒なのでこのブログのサンプルでは使わないと思いますw

    この宣言は、ソースコードを書いた人以外の人が見た時に、ByValならば値は変更されない、ByRefならば値を受け取るのだと、関数の中身を見なくてもわかるためなので、プログラマーを目指すなら書くべき!
    ま、ただの人なら書かなくてもいいですけどねーw

    次はどのメソッドを調べましょうかね?

    ではでは

  • FileExistsの使い方とサンプル|VBAでファイル存在チェック

    FileExistsの使い方とサンプル|VBAでファイル存在チェック

    Excel VBAを使用した場合、ExcelファイルのOpenはWorkbooksオブジェクトで行うので、FileSystemObjectでよく使用するのは、ファイルの存在確認を行うFileExistsメソッドかも知れません!

    ■FileExistsメソッド

    先にも書きましたが、ファイルの存在を確認するメソッドです

    ・構文

    構文は以下の通りです

    object.FileExists(filespec)

    objectはFileSystemObjectのオブジェクトです

    ・パラメータ

    メソッドのパラメータは以下の通りです

    • filespec … 存在を確認するファイルパス

    存在確認を行うファイルのフルパスを指定します(相対パス、もしくは絶対パスにて指定可能)

    ・戻り値

    メソッドの戻り値は以下の通りです

    • True … ファイルが存在する
    • False … ファイルが存在しない

    パラメータで指定したファイルが存在する場合はTrueを返し、存在しない場合はFalseを返します

    ■例

    ・簡単なサンプル

    ①FileExistsのサンプル

    VB
    Function FileExists_Sample(filespec As String) As Boolean
        Dim obj     As FileSystemObject
        Dim ret     As Boolean
    	
        ' オブジェクトを作成
        Set obj = New FileSystemObject
    	
        ' ファイルの存在確認
        ret = obj.FileExists(filespec)
    	
        ' オブジェクトを破棄
        Set obj = Nothing
    	
        ' 結果を返す
        FileExists_Sample = ret
    	
    End Function
    

    ②呼び出し元関数のサンプル

    VB
    Sub CallFileExists_Sample()
        Dim filespec	As String
    	
        ' 調べたいファイルパス
        filespec = "E:\VBA\Sample001\Sample.txt"
    	
        ' 作成した関数を呼び出す
        If (FileExists_Sample(filespec) = True) Then
            ' 戻り値がTrueなら存在する
            Debug.Print "ファイルは存在します"
    		
        Else
            ' 戻り値がTrue以外(False)なら存在しない
            Debug.Print "ファイルは存在しません"
    		
        End If
    	
    End Sub
    

    ③簡略化したFileExistsのサンプル

    VB
    Function FileExists_Sample2(filespec As String) As Boolean
        ' オブジェクトを作成
        With New FileSystemObject
            ' ファイルの存在確認結果を返す
            FileExists_Sample2 = .FileExists(filespec)
    		
        End With
    	
    End Function
    

    ・説明

    FileSystemObject型の変数でオブジェクトを作成しないといけませんので、関数化して呼び出すのが便利かと思います

    ガッツリ書くのであれば、①の方式で書いて、エラートラップや以下の引数チェックをやるのも良いかも知れません

    • 空文字ではないか?
    • ファイルパス形式か?

    簡略化したい場合は、③のようにすればかなりスッキリします!(まぁ、素敵w)

    ②は呼び出し元ですが、①も③もどちらを呼んでも同じ結果になります!(そりゃそうですねw)

    ・注意点

    特にないのですが、根本的なことなので個々のメソッドで書く必要はないのですが、以下に注意です

    • FileSystemObjectのオブジェクトを作成する場合は、NewでSetしてください!
    • 特に③を使用する場合、Newを書き忘れてもVBA的にはコーディングエラーではなく、実行時エラーになりますのでご注意ください
    • エラートラップやパラメータチェックについては、お任せしますw

    ・その他

    関数の呼び出し毎にFileSystemObjectのオブジェクトを作成したくない人は、標準モジュールではなくクラスモジュールでクラス化してください

    • Class_InitializeイベントでNew FileSystemObject
    • Class_TerminateイベントでNothing

    よく使いそうなメソッドについては、個別にサンプルを作っていこうと思います!

    ではでは

  • FileSystemObjectの使い方|VBAでファイル操作・存在確認を完全攻略

    FileSystemObjectの使い方|VBAでファイル操作・存在確認を完全攻略

    Excelマクロを使用して、ファイル操作を行うこともあるでしょう!

    ファイルを開くときには、ファイルが存在しているかを確認しておかないと、新規作成されてしまったり、エラーになったりしてしまいます

    ファイルの存在チェックと聞いて思い出すのは、Dir関数という人も多いですが、ファイルパスが長くなると、Dir関数では扱えないので、汎用性の高いFileSystemObjectについてもう少し調べておきたいと思います

    ■FileSystemObjectオブジェクト

    Objectオブジェクトって妙ですがw

    フォルダやファイルの存在確認・作成・コピー・削除したり、テキストファイルを新規作成やオープンして、そのTextStreamオブジェクトを取得することができます

    ・構文

    構文は以下の通りです

    Scripting.FileSystemObject

    以下の「Excel VBAの参照設定」でも少し触れましたが、FileSystemObjectは、Scriptingライブラリの持ち物です!w

    https://zesys.net/excel/setting/vba-reference/

    ・メソッド

    オブジェクトのメソッドは以下の通りです

    • BuildPath … パスにフォルダやファイル名を追加
    • CopyFile … 1 つ以上のファイルをコピー
    • CopyFolder … 1 つ以上のフォルダをコピー
    • CreateFolder … 新しいフォルダを作成
    • CreateTextFile … 新規に作成したテキストファイルのTextStream オブジェクトを取得
    • DeleteFile … 1 つ以上のファイルを削除
    • DeleteFolder … 1 つ以上のフォルダを削除
    • DriveExists … ドライブが存在するかどうか
    • FileExists … ファイルが存在するかどうか
    • FolderExists … フォルダーが存在するかどうか
    • GetAbsolutePathName … フルパスを取得
    • GetBaseName … ファイルまたはフォルダのベース名を取得
    • GetDrive … パスのドライブオブジェクトを取得
    • GetDriveName … パスのドライブ名を取得
    • GetExtensionName … ファイル拡張子を取得
    • GetFile … パスのファイル オブジェクトを取得
    • GetFileName … パスのファイル名またはフォルダ名を取得
    • GetFileVersion … ファイルのファイルバージョンを取得
    • GetFolder … パスのフォルダー オブジェクトを取得
    • GetParentFolderName … パスの親フォルダ名を取得
    • GetSpecialFolder … Windows の特殊フォルダのパスを取得
    • GetStandardStream … 標準入出力のStreamを取得
    • GetTempName … 一時ファイルまたはフォルダを取得
    • MoveFile … 1 つ以上のファイルを移動
    • MoveFolder … 1 つ以上のフォルダを移動
    • OpenTextFile … 開いたファイルのTextStreamオブジェクトを取得

    珍しく、全部のメソッドを書いてみました!w

    それだけ重要?使える!という印象です

    サイトに寄っては、FileオブジェクトやTextStreamオブジェクトのメソッドとごちゃ混ぜになっているところもありますが、これが正解です!(知らんけどw)

    ・プロパティ

    オブジェクトのプロパティは以下の通りです

    • Drives … ドライブのコレクションを取得

    全てのプロパティを・・・って、1つしかないですけどねw

    ■例

    ・簡単なサンプル

    VB
    Sub FileSystemObject_Sample()
        Dim obj     As FileSystemObject
        Dim oTxt    As TextStream
        Dim oDrv    As Drive
        Dim path    As String
        Dim path1   As String
        Dim path2   As String
        Dim path3   As String
        Dim prnt    As String
        Dim file1   As String
        Dim file2   As String
        Dim file3   As String
        
        Const STR_DRIVE_NAME    As String = "E:"
        
        Set obj = New FileSystemObject
        
        With obj
            ' ドライブは存在するか
            If (.DriveExists(STR_DRIVE_NAME) = True) Then
                Debug.Print "DriveExists(STR_DRIVE_NAME) = True"
                
                ' ドライブ名を取得
                Set oDrv = .GetDrive(STR_DRIVE_NAME)
                Debug.Print "GetDrive(STR_DRIVE_NAME) : " & oDrv.path
                
                ' パスを作成する(ドライブ名に「VBA」フォルダを結合している)
                path = .BuildPath(oDrv.path, "VBA")
                Debug.Print "BuildPath : " & path
                
                ' フォルダが存在しない場合
                If (.FolderExists(path) = False) Then
                    Debug.Print "FolderExists(path) = False"
                    ' フォルダを作成
                    Call .CreateFolder(path)
                End If
                
                ' 「VBA」フォルダのパスに「Sample001」を結合
                path1 = .BuildPath(path, "Sample001")
                Debug.Print "BuildPath : " & path1
                
                ' 「Sample001」のパスが存在しない場合
                If (.FolderExists(path1) = False) Then
                    Debug.Print "FolderExists(path1) = False"
                    ' フォルダを作成
                    Call .CreateFolder(path1)
                End If
                
                ' 「VBA」フォルダのパスに「Sample002」を結合
                path2 = .BuildPath(path, "Sample002")
                Debug.Print "BuildPath : " & path2
                
                ' 「Sample002」のパスが存在しない場合
                If (.FolderExists(path2) = False) Then
                    Debug.Print "FolderExists(path2) = False"
                    ' 「Sample001」フォルダを「Sample002」フォルダにコピー
                    Call .CopyFolder(path1, path2)
                End If
                
                ' 「VBA」フォルダのパスに「Sample003」を結合
                path3 = .BuildPath(path, "Sample003")
                Debug.Print "BuildPath : " & path3
                
                ' 「Sample003」のパスが存在しない場合
                If (.FolderExists(path3) = False) Then
                    Debug.Print "FolderExists(path3) = False"
                    ' 「Sample001」フォルダを「Sample002」フォルダに移動
                    Call .MoveFolder(path2, path3)
                End If
                
                ' 「Sample003」のパスの親階層を取得
                prnt = .GetParentFolderName(path3)
                Debug.Print "ParentFolderName : " & prnt
                
                ' 「Sample003」のパスが存在する場合
                If (.FolderExists(path3) = True) Then
                    ' フォルダを削除
                    Call .DeleteFolder(path3)
                End If
                
                ' ドライブ名を取得
                Debug.Print "DriveName : " & .GetDriveName(prnt)
                ' フォルダオブジェクトを取得
                Debug.Print "Folder : " & .GetFolder(prnt)
                
                ' 「Sample001」フォルダのパスに「Sample1.txt」を結合
                file1 = .BuildPath(path1, "Sample1.txt")
                Debug.Print file1
                
                ' 「Sample1.txt」が存在する場合
                If (.FileExists(file1) = True) Then
                    Debug.Print "FileExists(file1) = True"
                    ' OpenTextFileメソッドでファイルを開く
                    Set oTxt = .OpenTextFile(file1)
                Else
                    ' 存在しない場合
                    Debug.Print "FileExists(file1) = False"
                    ' CreateTextFileメソッドでファイルを作成
                    Set oTxt = .CreateTextFile(file1)
                End If
                
                ' 「Sample1.txt」のフルパスを取得
                Debug.Print "AbsolutePathName : " & .GetAbsolutePathName(file1)
                ' 「Sample1.txt」のベース名を取得
                Debug.Print "BaseName : " & .GetBaseName(file1)
                ' 「Sample1.txt」の拡張子を取得
                Debug.Print "ExtensionName : " & .GetExtensionName(file1)
                ' 「Sample1.txt」のFileオブジェクトを取得
                Debug.Print "File : " & .GetFile(file1)
                ' 「Sample1.txt」のファイル名を取得
                Debug.Print "FileName : " & .GetFileName(file1)
                ' 「Sample1.txt」のファイルバージョンを取得
                Debug.Print "FileVersion : " & .GetFileVersion(file1)
                
                ' 「Sample001」フォルダのパスに「Sample2.txt」を結合
                file2 = .BuildPath(path1, "Sample2.txt")
                Debug.Print "file2 : " & file2
                
                ' 「Sample2.txt」が存在しない場合
                If (.FileExists(file2) = False) Then
                    ' 「Sample1.txt」を「Sample2.txt」にコピー
                    Call .CopyFile(file1, file2, True)
                End If
                
                ' 「Sample001」フォルダのパスに「Sample3.txt」を結合
                file3 = .BuildPath(path1, "Sample3.txt")
                Debug.Print "file3 : " & file3
                
                ' 「Sample3.txt」が存在しない場合
                If (.FileExists(file3) = False) Then
                    Debug.Print "FileExists(file3) = False"
                    ' 「Sample2.txt」を「Sample3.txt」に移動
                    Call .MoveFile(file2, file3)
                End If
                
                ' 「Sample3.txt」が存在する場合
                If (.FileExists(file3) = True) Then
                    Debug.Print "FileExists(file3) = True"
                    ' 「Sample3.txt」を削除
                    Call .DeleteFile(file3)
                End If
                
                ' 特殊フォルダ(Windows オペレーティング システム)のパスを取得
                Debug.Print "WindowsFolder : " & .GetSpecialFolder(WindowsFolder)
                ' 特殊フォルダ(System フォルダ)のパスを取得
                Debug.Print "SystemFolder : " & .GetSpecialFolder(SystemFolder).csv
                ' 特殊フォルダ(一時ファイルの格納に使用される Temp フォルダ)のパスを取得
                Debug.Print "TemporaryFolder : " & .GetSpecialFolder(TemporaryFolder)
                ' 一時ファイルを取得
                Debug.Print "TempName : " & .GetTempName()
                
                Set oDrv = Nothing
                Set oTxt = Nothing
                
            End If
            
        End With
        
        Set obj = Nothing
    End Sub
    

    ・説明

    メソッドをふんだんに使ってみましたw

    その結果、何が何だかわからなくなりましたw

    実行結果を貼り付けておきます!

    あ、プロパティ使い忘れた!

    実行結果

    ・注意点

    • コメントは付けましょう!w
    • プロパティもお忘れなく!
    • DriveNameとフォルダ名をBuildPathしても「¥」を付けてくれない
    • 開いたファイルはTextStreamオブジェクトで読み書きします
    • GetFileはFileオブジェクトで操作します
    • GetFolderはFolderオブジェクトで操作します

    ・その他

    サンプルのコメントは後日付けますw

    各メソッドのリファレンスも付けておきたいところですが、それはおいおいで!

    今日は眠いので、この辺にしておきます

    ではでは