[教えて!VBA] 第7回 フォルダを開く(+ファイルを操作する)にはどうすればいいの??

概要

この記事について

かんたんな概要と結論

フォルダを開くには、
エクスプローラを起動して開く、ダイアログボックスで開くの二通りが存在します。

また、操作したいファイルが有るフォルダが固定であれば、
APIを用いてバックグラウンドでファイルを開いて操作することができます。

こんにちは、dedeです。

この記事では、
VBAマクロに関する質問のうち、
皆が疑問に思っているトピックについて解説いたします。

今回は、 VBAマクロからフォルダを開く(+α ファイルを操作する)方法
を解説いたします。

※この記事は、Office VBAマクロのうち
Excel VBAマクロに関するトピックです。

レベル:中級者向け

やりたいこと

特定フォルダの内容をチェックしたり、
CSVなどの外部ファイルの内容を取り込んだりすることは
VBAマクロにおいてしばしば要求される処理の一つです。

マクロで「フォルダを開く」という動作にはいくつか種類があり、

  1. エクスプローラ(ファイル閲覧、管理するアプリケーション)上でフォルダを開く
  2. ダイアログボックス画面を開き、ユーザにファイル・フォルダを選択させる
  3. 組み込み関数やAPIを用いてフォルダ内を探索する などを、目的に合わせて採用することになると思われます。

ただフォルダを開いて内容を視認することが目的であれば「1. 」を、
利用者が操作するファイルを選ぶことができることを目的とするのであれば「2. 」を、
すでに操作するファイルの置かれたフォルダの場所が決まっているのであれば「3. 」を採用するのが良いでしょう。

フォルダを開くだけの場合

フォルダを開くには、

  1. ハイパーリンクの仕組みを利用する方法
  2. 外部プログラムを実行する方法(Shell) の二種類が存在します。

フォルダを開くだけの場合

ハイパーリンクの仕組みを利用する方法

ABOUT

WorkbookオブジェクトのFollowHyperlinkメソッドを利用します。

1Workbook.FollowHyperlink(引数)
2'// メソッドの詳細はこちらを参照 https://vbabeginner.net/open-web-page-without-hyperlink/

このメソッドは、
Excelシート上のハイパーリンク押下時の挙動と同様の動作をしてフォルダを開きます。

ご存知かもしれませんが、
Excelシートにハイパーリンクを設定して、WebサイトのURLやブック内のセル番地ではなく
フォルダのパス(C:\temp~など)を指定すると、
リンクを押下したときにエクスプローラが起動し、指定したフォルダが開かれます。

その仕組みを利用します。

コード

次のコードを実行すると、
引数Addressで指定したパスのフォルダを、
エクスプローラで開きます。

1
2Sub ハイパーリンクの仕組みを利用する関数()
3    Dim path As String
4    path = "C:\temp\"
5    Application.ThisWorkbook.FollowHyperlink Address:=path
6End Sub

外部プログラムを実行する方法(Shell)

ABOUT

Shell関数というVBAにもともと備わっている関数を利用します。

Shell関数とは、
外部の実行可能プログラム(アプリケーション)を指定して実行する事ができる機能を持っている関数です。

起動可能なアプリケーションは、
エクスプローラ、メモ帳、拡張子exeの各種ファイルなど多岐にわたります。

今回は、
Shell関数を利用してエクスプローラからフォルダを開きます。

コード

次のように書きます。

1
2Sub Shell関数を利用するパターン()
3    Call Shell("explorer ""C:\temp\""", vbNormalFocus)
4    '// 詳細な引数の指定方法はこちらを参照 https://vbabeginner.net/shell/
5End Sub
6

最初の引数には、
利用するアプリケーションパス(今回はexplorer。環境変数でパス解決されるため、explorerの文字だけで問題なし)と、
その後にフォルダパス名を記載する文字列を指定します。

その後、2つ目の引数で、
起動時のエクスプローラの開き方(最小化、最大化、非表示など)を指定します。
今回はvbNormalFocusとして、前回起動時のウィンドウ状態に準拠させます。

フォルダの中のファイルを操作する場合

フォルダを開くだけでなく、
フォルダ内のファイルを操作したい場合は、
上述の

  1. ダイアログボックス画面を開き、ユーザにファイル・フォルダを選択させる
  2. 組み込み関数やAPIを用いてフォルダ内を探索する

の方法を利用します。

ダイアログボックスから手動で選択する場合

ABOUT

ダイアログボックスから手動で選択する場合

上の図のように、
マクロからダイアログボックスを起動し、
手動で選択したファイルを取り扱います。

コード

メイン関数である「ダイアログボックス経由でファイル情報出力」から、
機能別に分けられたサブ関数2種類を呼び出しています。

 1Sub ダイアログボックス経由でファイル情報出力()
 2    Dim filePath As String
 3    
 4    filePath = サブ関数_ダイアログボックス表示してファイルパス取得()
 5    
 6    If filePath <> "" Then
 7        サブ関数_ファイルの情報をシートに出力 (filePath)
 8    End If
 9    
10End Sub
11
12Function サブ関数_ダイアログボックス表示してファイルパス取得() As String
13    With Application.FileDialog(msoFileDialogFilePicker)
14        '//フィルタ設定 テキストファイルだけ選択可能に制限する
15        .Filters.Clear
16        .Filters.Add "テキストファイル", "*.txt"
17        
18        '//複数ファイル選択不可能に設定
19        .AllowMultiSelect = False
20        .Title = "ファイル選択"
21        
22        '//ファイル選択した場合に「Show」がTrueになる
23        '//ファイル選択せず閉じた場合はFalse
24        If .Show = True Then
25            サブ関数_ダイアログボックス表示してファイルパス取得 = .SelectedItems(1)
26        End If
27    End With
28End Function
29
30Sub サブ関数_ファイルの情報をシートに出力(ByVal filePath As String)
31    Dim fso As Object
32    Dim myFile As Object
33    '//ファイル取り扱う機能を持つオブジェクトを取得(FileSystemObject)
34    Set fso = CreateObject("Scripting.FileSystemObject")
35    
36    '//パスで指定されたファイルを取得
37    Set myFile = fso.GetFile(filePath)
38    
39    '//A1セルにファイル作成日時を出力
40    ActiveSheet.Range("A1").Value = myFile.DateCreated
41    
42    '//A2セルにテキストファイルの一行目の文字列を出力
43    With myFile.OpenAsTextStream
44        ActiveSheet.Range("A2").Value = .ReadLine
45        .Close
46    End With
47End Sub
48

デモ

上記コードを実行すると、
ダイアログボックスが表示され、ファイルを選択できます。

その後、
シートのA1セルにファイルの作成日時が、
A2セルにファイルの一行目の内容が出力されます。

マクロ実行前

マクロ実行後

組み込み関数やAPIを利用する場合

ABOUT

ダイアログボックスを利用しない、
つまり探索するフォルダがすでに決まっているならば、
VBA組み込み関数(Dir)やファイルシステムAPI(FileSystemObject)を利用して、
バックグラウンドですみやかにファイルの操作を行うことができます。

Dir(および他のVBA組み込み関数)よりもFileSystemObjectのほうが
直感的で高性能のため、
以下ではFileSystemObjectを利用してフォルダ内のファイルの探索をするデモコードを説明します。

コード

 1
 2Sub 組み込み関数やAPIを利用するパターン()
 3    Dim fso As Object
 4    Dim folderPath As String
 5    Dim myFolder As Object
 6    Dim myFile As Object
 7    Dim i As Long
 8    
 9    '//ファイル取り扱う機能を持つオブジェクトを取得(FileSystemObject)
10    Set fso = CreateObject("Scripting.FileSystemObject")
11    
12    '//フォルダパス(固定:ユーザには選択させない)
13    folderPath = "C:\temp\"
14    
15    '//フォルダの取得
16    Set myFolder = fso.GetFolder(folderPath)
17    
18    '//フォルダ中のテキストファイル(拡張子txt)のファイルのみ対象として
19    '//一行目の文字列データをシートに出力
20    i = 1
21    For Each myFile In myFolder.Files
22        '//テキストファイルかどうかをチェック
23        If fso.GetExtensionName(myFile.path) = "txt" Then
24            '//セルにテキストファイルの一行目の文字列を出力
25            With myFile.OpenAsTextStream
26                ActiveSheet.Cells(i, 1).Value = .ReadLine
27            End With
28            i = i + 1
29        End If
30    Next
31    
32End Sub

デモ

tempフォルダに次のようにファイルが格納されているとします。

1
2Mode                 LastWriteTime         Length Name
3----                 -------------         ------ ----
4-a----        2022/01/03     14:42             76 another-text01.csv
5-a----        2022/01/03     14:42             76 another-text02.json
6-a----        2022/01/03     13:38             76 mytext01.txt
7-a----        2022/01/03     14:20             76 mytext02.txt
8-a----        2022/01/03     14:42             76 mytext03.txt
9

コードを実行すると、
mytext(拡張子txtのファイル)のみを対象として、
シートにファイルの内容を出力します。

マクロ実行前

マクロ実行後

終わりに

フォルダの取り扱いには様々あります。

実現したい機能に合わせて、
適切な方法を選択できるようになると、
マクロの表現の幅が広がるでしょう。

関連記事

comments powered by Disqus