カテゴリー: ファイル一覧

Excel VBAを使ったファイル一覧を作成しています!少しずつではありますが、学習した内容を反映させながら、作業効率の向上を目指したツールにアップグレードさせていこうと思います

  • ファイル一覧の注意事項

    【環境】Windows 10 Pro 64bit、Excel for Office 365

    終わったはずのファイル一覧の作成ですが、ちょっと気になることがあるので、番外編として書いてみますw

    ■大事

    なのは?

    「一覧表で最も大事なことは何か!?」そう聞かれたら、何と答えますか?

    もちろん、正解が何かは知りませんし、プログラマーの個人の勝手な見解を押し付けるつもりですが・・

    ファイル一覧を思い出してみましょう!?

    どれが大事?

    最も大事なのは・・さて、どれでしょうか?

    • ファイルがどこにあるか?
    • ファイル名が何か?
    • ファイルの種類が何か?
    • ファイルの大きさはいくらか?
    • ファイルがいつ作成されたのか?
    • ファイルがいつ更新されたのか?

    これだけ書けばお気づきですよね?

    ■答え!

    「最も大事なのは、No.です!」・・・w

    『そこっ!?』って、思いますよね?

    『何が大事なん!?』って、笑っちゃいますよね?w

    ■本気!

    マジで大事なんですよー!

    だって、ファイル一覧を例にとっても、この中で、ユニーク(一意)な値は、「No」なのです!?・・・?

    『ファイル名もユニークやん!?』って、思うかも知れませんが、それはこのサンプルに限った話でしかありません

    違うフォルダに同じファイル名は格納できてしまいます

    そうなると、1つのファイルを特定するには、最低でもフォルダ名とファイル名の2つが必要になります

    でも、Noだけは、たった1つで1つのファイルを特定できるユニークキーなのです!!!

    ■ユニークキー

    個人を特定するための情報を考えてみても、様々な情報がありますよね?

    • 名前
    • 性別
    • 生年月日(年齢)
    • 住所
    • 電話番号
    • 身長
    • 体重
    • 血液型
    • 職業
    • etc…

    しかし、これらは、例え名前であっても、たった1つの情報で個人を特定することはできませんよね?

    複数が一致して初めて、個人を特定することができます!以前、テレビで夫婦で同姓同名って人が紹介されていましたが・・郵便物とか困るだろうね?w

    だから、個人を特定する「一意な値(ユニークキー)」として、『マイナンバー』ってのができたんですよ!?(知らんけどw)

    強引ですが、番号は大事なのです!

    ページ: 1 2

  • ファイル一覧作成

    ファイル一覧作成

    【環境】Windows 10 Pro 64bit、Excel for Office 365

    ExcelマクロのVBAを使用して、ファイル一覧を作成しています

    さていよいよですが、最後に、一覧作成ボタンと一覧消去ボタンの処理を作成していきます

    ファイル一覧
    ファイル一覧

    ■出力項目

    その3で実施した通り、ファイル一覧を作成するために、Fileオブジェクトを保存するようにしました

    [blogcard url=”https://zesys.net/pc/excel/vba-file-list-vol3/”]~その3:ファイル検索~[/blogcard]

    このFileオブジェクトが持つ情報を基にして、以下の内容を一覧に出力していきます

    • サブフォルダ名
    • ファイル名
    • タイプ
    • サイズ
    • 作成日時
    • 更新日時

    ■やること

    一覧作成ボタンを押下した際に行うことは、ざっくりと以下になります

    • シート情報の取得
    • 出力先ワークシートの取得
    • 一覧消去
    • ファイル情報取得
    • リスト作成

    細かいことを言えば、以下のこともやらなきゃですが、今回はw

    • 出力シートの有無確認
    • 出力シートの作成/削除/複製
    • 出力及び、出力済み一覧消去等の確認メッセージ表示
    • 出力中の進捗状況表示

    ・シート情報の取得

    これは表紙に記載された以下の内容を取得するということですが、その2で行ったように、ボタンへのマクロ登録時に、引数として渡す方法で、実装していきます

    • カレントフォルダ
    • ファイルパターン
    • 出力シート名

    やり方を忘れた方は、こちらを確認してください

    [blogcard url=”https://zesys.net/pc/excel/vba-file-list-vol2/”]~その2:フォルダ参照~[/blogcard]

    MakeListButtonにマクロの登

    引数でセル指定の文字列を受け取りって、セルの値を取得します

    Sub MakeList(cell1 As String, cell2 As String, cell3 As String)
    Dim path As String
    Dim ptrn As String
    Dim name As String

    path = Me.Application.ActiveSheet.Range(cell1).Text
    ptrn = Me.Application.ActiveSheet.Range(cell2).Text
    name = Me.Application.ActiveSheet.Range(cell3).Text
    End Sub

    あまり、わしは、「Me.Application.ActiveSheet」なんてのを沢山書くのは好きではないです

    更に、この「ActiveSheet」はプロパティなんですけど、見ての通り、型が「Object」型なので、WorkSheet型の変数にSetして使うようにしています

    ActiveSheetの型
    Sub MakeList(cell1 As String, cell2 As String, cell3 As String)
    Dim wb As Workbook
    Dim ws As Worksheet
    Dim path As String
    Dim ptrn As String
    Dim name As String
    Set wb = Me.Application.ActiveWorkbook
    Set ws = wb.Worksheets("表紙")
    path = ws.Range(cell1).Text
    ptrn = ws.Range(cell2).Text
    name = ws.Range(cell3).Text
    Set ws = Nothing
    Set wb = Nothing
    End Sub

    大したことではないのですが、Activeってのは、現在の最前面のウィンドウのこと(正確には違いますけどw)

    Excelを複数開いていたりすると、Excelのウィンドウを切り替えた場合に、Activeが意図しないものに変わってしまいエラーの原因になります

    そのため、Activeはボタンに登録するマクロで1回だけ、最初に使うだけにしましょー!

    できれば、「表紙」も引数でもらえばいいですね!

    ・出力先ワークシートの取得

    沢山ソースを書くのが、面倒になってきたので、抜粋していきますw

    引数でもらった出力先シート名のセルの値を「name」に格納しているので、これを使って、シートのオブジェクトを取得します

        Dim trg As Worksheet
    
    Set trg = wb.Worksheets(name)
    ' Set trg = wb.Sheets(name) これでも同じです
    Set trg = Nothing

    WorkBook型やWorkSheet型は変数宣言をして、Setでオブジェクトを取得し、使い終わったら、「Set (変数名) = Nothing」で開放しましょー

    ・一覧消去

    これは「一覧消去」ボタン押下時にも呼び出せるように、サブ関数化しておきましょ!こんな感じにw

    Sub ClearListSub(ws As Worksheet)
    Dim row As Long
    Dim col As Long
    Dim rows As Long
    Dim cols As Long

    row = 2 ' データ開始行
    col = 1 ' Noの列
    cols = 7 ' 列数
    rows = 100 ' 行数

    ws.Range(ws.Cells(row1, col1), ws.Cells(row2, col2)).ClearContents
    End Sub

    わかりやすく書いているつもりですが、本来は列数や行数は別の方法で取得していますし、ClearContentsの処理も別関数に切り出しています

    Sub ClearListSub(ws As Worksheet)
    Dim row As Long
    Dim col As Long
    Dim rows As Long
    Dim cols As Long

    row = LNG_START_ROW
    col = LNG_START_COL
    cols = GetLastCol(ws, row - 1) - col + 1
    rows = GetLastRow(ws, col) - row + 1

    Call ClearCellContents(ws, row, col, rows, cols)
    End Sub

    定数やサブ関数の中身は、ご想像にお任せしますw いつか公開するかもですが、想像つきますよねー?

    ・ファイル情報取得

    これは「その3」で説明したので、割愛しますw

    [blogcard url=”https://zesys.net/pc/excel/vba-file-list-vol3/”]~その3:ファイル検索~[/blogcard]

    ・リスト作成

    あとはファイル情報取得で取得したdataを以下のように関数に渡して、For…Eachステートメントで回しながら、Fileオブジェクトに取得して、各プロパティを出力項目に割り当てていくだけです!

    Sub MakeListSub(ws As Worksheet, data As Collection, path As String)
    Dim row As Long
    Dim no As Long
    Dim fl As File

    row = LNG_START_ROW
    no = 0

    For Each fl In data
    ' No.
    ws.Cells(row + no, 1).Value = no + 1
    ' サブフォルダ名
    ws.Cells(row + no, 2).Value = Replace(fl.ParentFolder, path, "")
    ' ファイル名
    ws.Cells(row + no, 3).Value = fl.Name
    ' タイプ
    ws.Cells(row + no, 4).Value = fl.Type
    ' サイズ
    ws.Cells(row + no, 5).Value = fl.Size
    ' 作成日時
    ws.Cells(row + no, 6).Value = Format(fl.DateCreated, "yyyy/mm/dd hh:nn:ss")
    ' 更新日時
    ws.Cells(row + no, 7).Value = Format(fl.DateLastModified, "yyyy/mm/dd hh:nn:ss")
    ' Noをカウントアップ
    no = no + 1
    Next

    End Sub

    Valueにセットするのもサブ関数にしてしまう悪い癖があるので、判り易くベタに記載しておきますねw

    列番号もEnumで定義することをお勧めします!

    実際の一覧表を作成するときには、セルの罫線や書式の設定も必要になってきますので、その辺りはお好みで実装してください

    ■まとめると

    一覧作成ボタンのマクロをを以下に掲載しますが、エラーチェック等は割愛していますので、程々に実装してくださいねーw

    ' 一覧作成
    Sub MakeList(mysheet As String, cell1 As String, cell2 As String, cell3 As String)
    Dim wb As Workbook
    Dim ws As Worksheet
    Dim trg As Worksheet
    Dim path As String
    Dim ptrn As String
    Dim name As String
    Dim data As Collection

    ' アクティブなワークブックを取得する
    Set wb = Me.Application.ActiveWorkbook
    ' 表紙のワークシートを取得する
    Set ws = wb.Worksheets(mysheet)

    path = GetTextRange(ws, cell1) ' カレントフォルダ
    ptrn = GetTextRange(ws, cell2) ' ファイルパターン
    name = GetTextRange(ws, cell3) ' 出力先シート名

    ' 出力先
    Set trg = wb.Worksheets(name)

    ' 消去
    Call ClearListSub(trg)

    ' Fileオブジェクトを格納するコレクションを作成する
    Set data = New Collection

    ' ファイル取得
    Call GetFileInfo(data, path, ptrn)

    ' リスト作成
    Call MakeListSub(trg, data, path)

    ' 後処理
    Set data = Nothing
    Set trg = Nothing
    Set ws = Nothing
    Set wb = Nothing
    End Sub

    ■一覧消去ボタン

    上のまとめたソースから必要なものだけを残せば、一覧消去ボタン押下時の関数はできてしまいますよね

    Sub ClearList(mysheet As String, cell As String)
    Dim wb As Workbook
    Dim ws As Worksheet
    Dim trg As Worksheet
    Dim name As String

    Set wb = Me.Application.ActiveWorkbook
    Set ws = wb.Worksheets(mysheet)

    name = GetTextRange(ws, cell)
    Set trg = wb.Worksheets(name)

    Call ClearListSub(trg)

    Set trg = Nothing
    Set ws = Nothing
    Set wb = Nothing
    End Sub

    説明はいらないかな?w

    ■完成

    というわけで、無事に一覧表が完成しました!

    完成したファイル一覧
    完成したファイル一覧

    ■最後に

    今回はありきたりな画像ファイルを一覧するだけに留めていますが、何かとファイル一覧が必要になることは多いと思います

    これをベースにCSVやExcelファイルを一覧して、更に、そのファイルを開いて自動処理をしていくなんてことも考えられますよね!?

    もちろん、画像ファイルの一覧だって、これをベースにショッピングモールに出品する商品リストを作成するなんてことも・・

    というわけで、今後は、以下のようなことを書いていこうかと思います

    • セル制御、行挿入、列挿入、書式設定、条件付き書式、入力規則設定
    • Excelシート一覧、シートを開く、シートの成型
    • CSVファイル一覧、特定データの抽出、グラフ化、作表、集計
    • HTML解析…等

    やりたいことを挙げたらキリがないw

    時間との兼ね合いで、簡単なところから、手を付けていきたいと思います!

    ではでは

  • 再帰的にファイルを検索

    再帰的にファイルを検索

    【環境】Windows 10 Pro 64bit、Excel for Office 365

    さてさて、ファイル一覧を自動で作成するには、もちろんカレントフォルダ配下のファイルを検索する! これですよねー

    さー!作っていきましょー

    ※以下の記事でも記載しましたが、本来は実行時バインディングに簡単に変換できるようなコーディングをお勧めしています
    しかし、各記事の中では必要なコードだけを書いていますので、実際にご自身でコーディングされるときは、ご注意ください!

    [blogcard url=”https://zesys.net/pc/excel/vba-reference/”]Excel VBAの参照設定[/blogcard]

    ■FileSystemObject

    再三にわたり出てきているFileSystemObjectを使ってファイルを検索していきます! まずは指定したフォルダの直下のファイル名だけを表示するコードを書いてみます

    Sub GetFileInfo(path As String)
        Dim fl      As file    
        With New FileSystemObject
            ' pathのファイルを取得
            For Each fl In .GetFolder(path).files
                ' ファイル名を表示
                Debug.Print fl.name
            Next
        End With
    End Sub

    ・説明

    やることは単純で、以下の4つです

    • 引数で指定のフォルダパスを受け取り
    • FileSystemObjectを作成
    • GetFolderメソッドのFilesプロパティからFileオブジェクト単位で取得
    • Fileオブジェクトからファイル名を取得

    ・GetFolderメソッド

    構文は以下の通りで、指定フォルダのFolderオブジェクトを取得します

    指定フォルダが存在しないとエラーになりますが、指定フォルダのパス文字列の最後は「¥」じゃなくても良いです

    object.GetFolder(folderspec)

    • object:FileSystemObjectのオブジェクト
    • folderspec:指定フォルダのパス(絶対か相対)

    ・Filesプロパティ

    構文は以下の通りで、指定フォルダの全てのFileオブジェクトで構成されるFilesコレクションを取得します

    object.Files

    • object:Folderのオブジェクト

    ・Folderオブジェクト

    Folderオブジェクトには以下が含まれます(主なもの)

    • Copyメソッド
    • Deleteメソッド
    • Filesプロパティ
    • SubFoldersプロパティ
    • Moveメソッド
    • Nameプロパティ
    • Pathプロパティ

    ・Fileオブジェクト

    Fileオブジェクトには以下が含まれます(主なもの)

    • Copyメソッド
    • DateCreatedプロパティ
    • DateLastAccessedプロパティ
    • DateLastModifiedプロパティ
    • Deleteメソッド
    • Moveメソッド
    • Nameプロパティ
    • Pathプロパティ
    • Sizeプロパティ
    • Typeプロパティ
  • ExcelVBAのフォルダ参照ダイアログでフォルダを指定する

    ExcelVBAのフォルダ参照ダイアログでフォルダを指定する

    【環境】Windows 10 Pro 64bit、Excel for Office 365

    それでは早速?Excelシートに張り付けた「参照」ボタンを押下して、フォルダ参照のダイアログボックスを表示するプログラムを書いていきましょう!

    ※『その1:仕様』は、以下のリンクを確認してください

    [blogcard url=”https://zesys.net/pc/excel-macro/vba-file-list-vol1/”]Excelでファイル一覧を作成する~その1:仕様~[/blogcard]

    ■フォルダ参照ダイアログボックスを呼び出す関数

    ファイルを参照するダイアログボックスの開き方はいくつかあるようなのですが、フォルダを参照する方法はこれしか知りませんw

    FileDialog オブジェクトのフォルダピッカーを指定して、フォルダ参照ダイアログボックスを呼び出す関数を作成していきます

    Function UseFileDialogFolderPicker() As String
        Dim ret As String
        ret = "" 
        ' Create a FileDialog object as a Folder Picker dialog box. 
        With Application.FileDialog(msoFileDialogFolderPicker)
            ' Display paths of each file selected
            If (.Show = -1) Then
                ' The user pressed the button. 
                ret = Trim(.SelectedItems(1))
            Else
                ' The user pressed Cancel. 
            End If
        End With 
        UseFileDialogFolderPicker = ret
    End Function

    コメントはMicrosoftのサンプルを頂きましたw

    【参考】https://docs.microsoft.com/ja-jp/office/vba/api/office.filedialog

    簡単に解説します

    • 5行目:フォルダピッカーのオブジェクトを宣言します
    • 7行目:フォルダピッカーを開いて、アクションボタンが押された場合(キャンセルじゃなかったら)
    • 8行目:選択されたアイテムの1つ目を取得します
    • 14行目:関数の戻り値として返します

    ■FileDialogオブジェクト

    FileDialogオブジェクトのメンバーでフォルダ参照ダイアログボックスをカスタマイズできる項目を挙げておきます

    恐らくはこの3つのプロパティくらいですね

    • ButtonName:アクションボタンに表示する文字列を 取得または 設定
    • InitialFileName:最初に表示されるパスを 取得または 設定
    • Title:ダイアログボックスのタイトルを取得または設定

    これらのプロパティを使って書き換えてみます

    Function UseFileDialogFolderPicker() As String
        Dim ret As String
        ret = "" 
        ' Create a FileDialog object as a Folder Picker dialog box. 
        With Application.FileDialog(msoFileDialogFolderPicker)
            .ButtonName = "OK"
            .InitialFileName = "C:"
            .Title = "選択"
            ' Display paths of each file selected
            If (.Show = -1) Then
                ' The user pressed the button. 
                ret = Trim(.SelectedItems(1))
            Else
                ' The user pressed Cancel. 
            End If
        End With 
        UseFileDialogFolderPicker = ret
    End Function

    注意すべき点は、「宣言~Showまでの間で使用する」くらいですかね?

    フォルダ参照は複数選択できないので、SelectedItems(1)で良いです

    もちろん、エラートラップも必要かも知れませんが、ま、特に起きそうもないので、無くても良いかとw

    汎用的な使い方をする場合は、これらのプロパティを引数に持つというのも良いかも知れません

    その場合は、「InitialFileName」が存在するパスかどうかをチェックしないとエラーが発生する恐れがありますね!

  • Excel VBAを使って作成するファイル一覧の仕様について考える

    Excel VBAを使って作成するファイル一覧の仕様について考える

    【環境】Windows 10 Pro 64bit、Excel for Office 365

    Excel VBAを使用して、Excelシート上にカレントフォルダ配下のファイルを一覧する単純なツールをFileSystemObjectを使用して作成し、VBAの勉強をしていきます

    どんなファイル一覧を作成するのか、仕様を考えていきましょー

    ■ファイル一覧

    簡単なファイル一覧を作成するのに、仕様書を作るまでもないと考えていますが、作成後のイメージは必要と思いますので、以下に載せておきます

    シートの構成は以下の2つで、それぞれの画面イメージを載せていますが、シートを分けたのはセル幅を気にしただけのようにも見えますが、出力シートを都度指定できるようにするため、出力は別シートとしているのです!w

    • 入力用の表紙シート
    • 出力用の一覧シート
    ファイル一覧の入力用シートのイメージ
    ファイル一覧の出力用シートのイメージ

    ■入力用シート

    入力する情報(プロパティ)としては、以下の3点くらいで良いかと考えています

    • どこのフォルダを一覧するのか?
    • どんなファイルを一覧するのか?
    • どのシートに出力するのか?

    実施する処理(メソッド)としては、以下の4点くらいかと考えました

    • フォルダパスを指定する
    • フォルダパスを消す
    • 一覧を作成する
    • 一覧を消す
    入力用シート

    ・どこのフォルダ

    どこのフォルダにあるファイルを一覧するのか、それを指定するために、カレントフォルダの入力欄をシートに作成します

    ・どんなファイル

    今回は、拡張子が同じでもプレフィックスが一致するようなファイルのみを抽出したいなどもあるかと思い、ワイルドカードを使用してLIKE検索するようにしたいと思います

    ファイルを絞り込むのに、拡張子だけでいいのならば、拡張子を選択するような機能にしてもよいかと思いますし、ワイルドカードではなく、正規表現で一致させる方法もあるでしょう

    複数の拡張子やパターンが入力できても良いかも知れませんね!

    ・どのシート

    出力先のシート名はハードコーディングで固定でも良かったんですが、一覧の出力結果を残しておけるように、シート名を都度設定できるようにしてみます

    この場合、存在しないシートは作成するのか、存在しないからエラーとするのか、決めるべきところが残りますが、それはおいおい考えていきます

    ・フォルダパスを指定する

    手入力でもいいのですが、勉強のために「参照」ボタンを作成して、フォルダを指定できるようにしてみます

    今回はカレントフォルダとしていますので、指定したフォルダの配下にあるサブフォルダも全て検索する対象としていきます

    ・フォルダパスを消す

    入力欄をクリアするのもボタンを作成して行います!w

    セルを選択して、Deleteキーを押下するだけですが、ボタン一つで処理するようにします

    ・一覧を作成する

    ファイル一覧を作成するボタンを配置します

    カレントフォルダが指定されていなければ、存在しなければ、メッセージを表示して処理を行わないとします

    今回は、FileSystemObjectを使用して、まずはファイル(Fileオブジェクト)をコレクション(Collection)に格納して、全てのファイルを検索後に一覧を作成するようにします

    ・一覧を消す

    シートを削除するのか、結果の一覧部分だけを消去するのか、考えるところはありますが、とりあえずは指定した出力シートの出力内容を消すようにします

    ■出力用シート

    出力内容をどうしましょうか?と考えたのですが、FileSystemObjectのFIleクラスのメンバを出力しておく程度に留めます

    出力用シート

    ・何を出力する

    主力内容は以下になります

    • No:ファイル毎に一意の番号
    • サブフォルダ名:入力用シートで指定したカレントフォルダからの差分
    • ファイル名:対象のファイル名
    • タイプ:ファイルタイプ
    • サイズ:ファイルサイズ
    • 作成日時:ファイルの作成日時
    • 更新日時:ファイルの更新日時

    ■まとめ

    いくつか決めなければならない課題が残っていますが、そのあたりは作成しながら、考えていくことにします!

    本来は、仕様として決めておくべきことなのでしょうが、そこまでのことはしませんw

    ■次回

    意外と前置きとなる仕様の記載に時間がかかってしまったので、次回に「フォルダ指定の機能」と「クリア」くらいを作成していこうと思います