こんにちは!Microsoft Projectの自動化の世界へようこそ。
マクロの記録という「安全な浅瀬」から一歩踏み出し、いよいよ本格的なオブジェクトモデルとファイルシステムを操る領域に到達しましたね。
今回は、実務で絶対に役立つ「FileSystemObject(FSO)を用いた、プロジェクトのバージョン管理バックアップシステム」を一緒に作っていきます。
「昨日まで動いていたスケジュールに戻したい」「クライアントから『先週の計画と何が違うの?』と聞かれた」――そんな現場の修羅場を救う、実用性抜群の仕組みです。ここをクリアすれば、あなたも立派なProject VBAエンジニアの仲間入りです。一緒に優しく、深く、学んでいきましょう!
—
1. なぜ「MS Project × FSO」なのか?
Microsoft Projectには、プロジェクトを管理するための強力なオブジェクト(`Project`、`Task`、`Resource`など)が存在します。しかし、ファイル操作(ファイルのコピー、存在確認、フォルダ作成など)に関しては、VBAの古い標準関数(`FileCopy`など)を使うよりも、`FileSystemObject (FSO)`を使うのが圧倒的にスマートで安全です。
FSOを使う最大のメリットは、以下の点にあります。
- エラーハンドリングの美しさ: ファイルが存在するかどうか (`FileExists`) を事前にスマートにチェックできる。
- パス操作の強さ: フォルダのパスとファイル名を結合するとき、スラッシュやバックスラッシュのミスを防げる (`BuildPath`)。
今回は、プロジェクトを「上書き保存」するタイミングで、自動的に `YYYYMMDD_HHMMSS_ファイル名.mpp` という命名規則でタイムスタンプ付きのバックアップを生成する仕組みを構築します。
—
2. 全体像:バックアップシステムの設計
実装する仕組みの流れはこうです。
1. イベントのフック: ユーザーがプロジェクトを保存しようとした瞬間を捉える。
2. パスの取得: 現在開いているファイルの名前と保存先フォルダのパスを特定する。
3. バックアップフォルダの作成: 保存先と同じ階層に `Backup` フォルダがなければ、自動で作成する。
4. FSOによるファイルの複製: 現在のファイルを、日時を付与してバックアップフォルダへコピーする。
これを実現するために、MS Projectの「クラスモジュール(イベント処理)」と「標準モジュール」を組み合わせて使います。
—
3. 実装コード(そのままコピペして使えます)
それでは、実際のコードを見ていきましょう。
初学者の方にも迷いがないよう、すべての行に魂を込めてコメントを入れています。
① 標準モジュール(バックアップの核心ロジック)
まずは、ファイルをコピーする実務的な処理を書く標準モジュール(例: `modBackup`)です。
‘ Option Explicitはプログラミングの命綱です。変数の宣言漏れを防ぎます。
Option Explicit
Sub ExecuteBackup()
Dim fso As Object
Dim currentPath As String
Dim currentName As String
Dim backupDir As String
Dim timeStamp As String
Dim backupFileName As String
Dim targetFullPath As String
‘ 1. 現在のプロジェクトが一度も保存されていない場合は処理をスキップ
On Error Resume Next
currentPath = ActiveProject.Path
currentName = ActiveProject.Name
On Error GoTo 0
If currentPath = “” Then
MsgBox “このプロジェクトはまだ保存されていません。一度保存してから実行してください。”, vbExclamation, “バックアップ中断”
Exit Sub
End If
‘ 2. FileSystemObjectのインスタンスを生成
‘ ※参照設定不要の「レイトバインディング」を採用し、環境依存のエラーを防ぎます
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ 3. バックアップ保存先フォルダのパスを構築 (例: [元のフォルダ]\Backup)
backupDir = fso.BuildPath(currentPath, “Backup”)
‘ 4. Backupフォルダが存在しなければ、新しく作成する
If Not fso.FolderExists(backupDir) Then
fso.CreateFolder (backupDir)
End If
‘ 5. タイムスタンプの生成 (例: 20231025_143022)
timeStamp = Format(Now, “yyyymmdd_hhnnss”)
‘ 6. 拡張子(.mppなど)とファイル名を分離して、新しいファイル名を組み立て
Dim baseName As String
Dim extension As String
baseName = fso.GetBaseName(currentName)
extension = fso.GetExtensionName(currentName)
backupFileName = baseName & “_” & timeStamp & “.” & extension
targetFullPath = fso.BuildPath(backupDir, backupFileName)
‘ 7. 現在のファイルを上書き保存した上で、バックアップ先へコピー
‘ ※ProjectオブジェクトのSaveメソッドを確実に実行してからコピーします
ActiveProject.Save
‘ ファイルのコピー実行 (OverWriteFiles = True で上書き許可)
fso.CopyFile fso.BuildPath(currentPath, currentName), targetFullPath, True
‘ 8. メモリの解放
Set fso = Nothing
‘ 完了のログ(実務ではステータスバー表示にするとスマートです)
MsgBox “バックアップが完了しました:” & vbCrLf & backupFileName, vbInformation, “バージョン管理”
End Sub
—
4. 陥りやすい罠とエンジニアの知見
ここで、Project VBA特有の「罠」について少しお話しておきます。
⚠️ 罠1: まだ名前をつけて保存されていないプロジェクト
新規作成しただけで、一度もディスクに保存されていないプロジェクト(`ActiveProject.Path` が空の状態)に対してファイルをコピーしようとすると、当然エラーになります。
今回のコードでは、`currentPath = “”` の判定を入れて防いでいますが、実務ではこの「ファイルが存在する前提を疑う」というガードがシステムの頑健性を決めます。
⚠️ 罠2: 参照設定のバージョン違いエラー
FSOを使う際、`Tools(ツール) > References(参照設定)` から `Microsoft Scripting Runtime` にチェックを入れる解説書が多いですが、他人にファイルを配布するツールの場合、PCの環境によってこの参照が切れて「Compile Error」になることがあります。
私のオススメは、上記コードのように `CreateObject(“Scripting.FileSystemObject”)` を使うレイトバインディング手法です。これなら環境を選ばず、誰のPCでも動く神仕様になります。
—
5. さらに実用性を高めるために(イベント化への布石)
今回は「手動で実行するマクロ」としてご紹介しましたが、これをさらに進化させると、「ユーザーが上書き保存ボタンを押した瞬間(`ProjectBeforeSave` イベント)」に自動発火させることも可能です。
クラスモジュールを使ったイベントフックを組み合わせれば、ユーザーが意識することなく、勝手に過去のタイムラインがアーカイブされていく「完璧な要塞」が完成します。
ここをクリアできれば、もうマクロの記録の卒業生ではありません立派な自動化エンジニアです。ぜひ今日のコードを手元のProjectVBE(Alt + F11)に貼り付けて、動きを確認してみてください。
それでは、次回の高度なオブジェクト操作でお会いしましょう。あなたの開発ライフが素晴らしいものになりますように!
