【VBA】FSO(“Scripting.FileSystemObject”)|シングルトン化して使う
作成日:2022-12-02
更新日:2025-10-05

fsoをセットする
CreateObject(“Scripting.Dictionary”)を使う
Dim fso as Object
Set SetFSO = CreateObject("Scripting.FileSystemObject")
シングルトン化|Singleton pattern
モジュール変数に1個だけ作って、ずっとそれを使い回すこと
通常のやり方(非シングルトン)
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
これを毎回呼ぶたびに書くと、
- COMオブジェクトが何回も生成される(重い)
- メモリも少しずつ増える
- 特に大量ループで呼ぶとパフォーマンス低下
シングルトン化のやり方
' モジュール変数として保持
Private mFSO As Object
' 初回だけ生成、それ以降は同じインスタンスを返す
Private Function FSO() As Object
If mFSO Is Nothing Then
Set mFSO = CreateObject("Scripting.FileSystemObject")
End If
Set FSO = mFSO
End Function
' 解放
Public Sub ResetFSO()
Set pFSO = Nothing
End Sub
' ▽ 以下、必要なFSO系の関数を置く
' Return extension without a leading dot, "" if absent (FSO-conformant).
' 先頭ドットなしで拡張子を返す。なければ ""(FSOの仕様に合わせる)。
Public Function GetExtensionFSO(ByVal filePath As String) As String
GetExtensionFSO = FSO().GetExtensionName(filePath) ' e.g., "xlsx" or ""
End Function
' Return base name (filename without path), including extension.
' ベース名(パスを除いたファイル名、拡張子込み)を返す。
Public Function GetBaseNameFSO(ByVal filePath As String) As String
GetBaseNameFSO = FSO().GetFileName(filePath)
End Function
' Return parent folder path, "" if none.
' 親フォルダのパス。無ければ ""。
Public Function GetParentPathFSO(ByVal filePath As String) As String
On Error Resume Next
GetParentPathFSO = FSO().GetParentFolderName(filePath)
On Error GoTo 0
End Function
' Combine path segments robustly.
' パス結合(区切りの重複/欠落に強い)。
Public Function JoinPathFSO(ByVal parentPath As String, ByVal childName As String) As String
JoinPathFSO = FSO().BuildPath(parentPath, childName)
End Function
' Ensure directory exists (create if missing).
' ディレクトリが無ければ作成。
Public Sub EnsureFolderFSO(ByVal folderPath As String)
If Not FSO().FolderExists(folderPath) Then
FSO().CreateFolder folderPath
End If
End Sub
こうしておくと:
- 初回だけ CreateObject が実行される
- 2回目以降は既に生成済みのオブジェクトを返す
- COMの生成コストを一度きりにできる
使い方例|Usage
' Typical usage — no need to create/cleanup FSO each time.
' 典型例 — 呼ぶたびにFSO生成/破棄は不要。
Sub Sample()
Dim ext As String
ext = GetExtensionFSO("C:\data\sales.xlsx") ' → "xlsx"
Dim base As String
base = GetBaseNameFSO("C:\data\sales.xlsx") ' → "sales.xlsx"
Dim parent As String
parent = GetParentPathFSO("C:\data\sales.xlsx") ' → "C:\data"
Call EnsureFolderFSO(JoinPathFSO(parent, "backup"))
End Sub
これで、100回呼んでも内部では同じFSOインスタンスが使われ続ける。
どんな時に使う?
状況 | シングルトン化すべき? | 理由 |
---|---|---|
FSOをループ内で何回も使う | すべき | COM生成を最小化 |
一回しか使わない | 不要 | オーバーエンジニアリング |
共通ユーティリティとして複数関数から使う | 有効 | メモリ効率・速度向上 |
解放せずに保持してもいい?
FSOのモジュール内シングルトン保持はOK
- FSOは軽量で、外部資源を保持しない(ファイルを開いてるわけではない)
- 役割はパス操作、存在確認、ファイル/フォルダ作成の窓口
- 使い回しても副作用は小さい
- 逆に、都度
CreateObject
を繰り返すのはオーバーヘッドになりやすい
頻繁に呼ぶなら保持、たまにしか使わないなら都度生成でも可
参考|すぐ解放すべきもの
危険なのは“外部資源”
- 例:
TextStream
(ファイルストリーム)、ADODB.Connection
、Recordset
、Excel.Workbook
の開放忘れは危険。 - これらは**使い終わったら即
Close
+Set ... = Nothing
**が基本。
Referenced Insights & Citations
- Microsoft. (n.d.). FileSystemObject object (Scripting Runtime).
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/filesystemobject-object - Microsoft. (n.d.). OpenTextFile method (Scripting).
https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/windows-scripting/314cz14s(v=vs.84) - Microsoft. (n.d.). COM: Reference counting fundamentals.
https://learn.microsoft.com/en-us/windows/win32/com/through-the-looking-glass#reference-counting - Microsoft. (n.d.). Set statement / Nothing (VBA).
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/set-statement
(VBAではスコープを抜ければ参照は解放されるが、外部資源はCloseを忘れないのが実務原則)
| Singleton Pattern|シングルトンパターン |
| Module Variable|モジュール変数 |
| Object Reuse|オブジェクトの再利用 |
| Singleton Reuse|シングルトン再利用 |
| COM Object|COMオブジェクト |
| Memory Efficiency|メモリ効率 |
| Initialization Cost|初期化コスト |
| Reference Counting|参照カウント |
| External Resource|外部資源 |
| TextStream|テキストストリーム |
| Lifecycle Hook|ライフサイクルフック |
| Overhead|オーバーヘッド |
| Scope Release|スコープ解放 |
| Resource Leak|リソースリーク |
One instance,
reused efficiently.
That’s the heart of Singleton.
reused efficiently.
That’s the heart of Singleton.
2022-12-02
編集後記:
この記事の内容がベストではないかもしれません。
記事一覧
-
[VBA]openbook 【VBA】ブックを開く|OpenBook -
[VBA]get fso objectfrom path 【VBA】パスからfsoオブジェクトを取得する|fso.GetFolder/.GetFile -
グラフ設定を変更する 【VBA】グラフ設定を動的に変更する -
[VBA]Reset filtersand outlines 【VBA】オートフィルタ解除&非表示を表示する|.FilterMode/.Outline -
[VBA]Cells or Range 【VBA】.Cells と .Range の使い分け目安|数千か数万か -
ユーザーフォームを半透明にする 【VBA】ユーザーフォームを半透明にしてシートの内容が見えるようにする|waiting-form