ねらい:ブック・シート・CSV・版管理まで「毎回同じ手順」で自動バックアップする
バックアップは「いつ」「どこに」「何を」「何世代残すか」をブレなく実行することが命です。VBAなら“時刻スタンプ付きの安全なパス生成→保存形式(XLSX/CSV)→版数ローテーション→整合性チェック→ログ記録”の型にすれば、毎日の業務でも迷わず回せます。初心者でも貼って動くテンプレを、例題付きでかみ砕いて解説します。
共通基盤:時刻スタンプ・安全パス・ログ・簡易整合性チェック
ユーティリティ(貼って動く最小構成)
' ModBackup_Base.bas
Option Explicit
Public Function StampNow() As String
' 2025-12-19_1045 のようなスタンプを返す(分粒度)
StampNow = Format(Now, "yyyy-mm-dd_hhnn")
End Function
Public Function JoinPath(ByVal basePath As String, ByVal name As String) As String
If Right$(basePath, 1) = "\" Then
JoinPath = basePath & name
Else
JoinPath = basePath & "\" & name
End If
End Function
Public Function EnsureFolder(ByVal folderPath As String) As Boolean
On Error Resume Next
If Dir(folderPath, vbDirectory) = "" Then MkDir folderPath
EnsureFolder = (Dir(folderPath, vbDirectory) <> "")
On Error GoTo 0
End Function
Public Sub AppendLog(ByVal logPath As String, ByVal message As String)
Dim f As Integer: f = FreeFile
Open logPath For Append As #f
Print #f, Format(Now, "yyyy-mm-dd hh:nn:ss"); " | "; message
Close #f
End Sub
Public Function CheckFileExists(ByVal filePath As String) As Boolean
CheckFileExists = (Dir(filePath) <> "")
End Function
Public Function FileSize(ByVal filePath As String) As Long
If Dir(filePath) = "" Then FileSize = 0: Exit Function
Dim f As Object: Set f = CreateObject("Scripting.FileSystemObject").GetFile(filePath)
FileSize = f.Size
End Function
VB重要部分の深掘り
- 時刻スタンプは「yyyy-mm-dd_hhnn」を推奨。ソートが自然で、日次・分単位の重複も避けられます。
- フォルダ生成は毎回“存在チェック→必要なら作成”で安全化。ログはテキスト追記にすると監査が容易です。
- 整合性チェックは「存在+サイズ>0」の軽量検査から。必要ならハッシュ(MD5/SHA)追加も可能です。
ブック丸ごとバックアップ:XLSX/XLSMの安全保存と版ローテーション
ブック保存テンプレ
' ModBackup_Workbook.bas
Option Explicit
Public Sub BackupWorkbook(ByVal targetWB As Workbook, ByVal backupRoot As String, _
Optional ByVal keepGenerations As Long = 7)
' 1) フォルダ準備(例:...\Backup\BookName\2025-12-19_1045.xlsx)
Dim bookName As String: bookName = Replace(targetWB.Name, ".xlsm", "")
bookName = Replace(bookName, ".xlsx", "")
Dim bookFolder As String: bookFolder = JoinPath(backupRoot, bookName)
If Not EnsureFolder(backupRoot) Then MsgBox "バックアップルートを作成できません: " & backupRoot, vbExclamation: Exit Sub
If Not EnsureFolder(bookFolder) Then MsgBox "ブックフォルダを作成できません: " & bookFolder, vbExclamation: Exit Sub
' 2) 保存(拡張子は元に合わせる)
Dim stamp As String: stamp = StampNow()
Dim ext As String: ext = IIf(targetWB.FileFormat = xlOpenXMLWorkbookMacroEnabled, ".xlsm", ".xlsx")
Dim backupPath As String: backupPath = JoinPath(bookFolder, stamp & ext)
Application.DisplayAlerts = False
targetWB.SaveCopyAs backupPath
Application.DisplayAlerts = True
' 3) 整合性(存在+サイズ)
If Not CheckFileExists(backupPath) Or FileSize(backupPath) = 0 Then
AppendLog JoinPath(bookFolder, "backup.log"), "FAILED: " & backupPath
MsgBox "バックアップ失敗(存在しない/サイズ0): " & backupPath, vbExclamation
Exit Sub
End If
AppendLog JoinPath(bookFolder, "backup.log"), "OK: " & backupPath
' 4) 版管理(古い順に削除)
RotateGenerations bookFolder, ext, keepGenerations
End Sub
Private Sub RotateGenerations(ByVal folder As String, ByVal ext As String, ByVal keep As Long)
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
Dim fl As Object: Set fl = fso.GetFolder(folder).Files
Dim arr() As Variant, c As Long: c = 0
Dim fi As Object
For Each fi In fl
If LCase$(Right$(fi.Name, Len(ext))) = LCase$(ext) Then
c = c + 1: ReDim Preserve arr(1 To c)
arr(c) = fi
End If
Next
If c <= keep Then Exit Sub
' タイムスタンプ名前提で古い順に削除(作成日時でソートしてもOK)
Dim i As Long, j As Long, tmp As Object
For i = 1 To c - 1
For j = i + 1 To c
If arr(i).DateCreated > arr(j).DateCreated Then
Set tmp = arr(i): Set arr(i) = arr(j): Set arr(j) = tmp
End If
Next
Next
For i = 1 To c - keep
On Error Resume Next
arr(i).Delete True
On Error GoTo 0
Next
End Sub
VB重要部分の深掘り
- SaveCopyAsは“編集中でも安全にコピー”できるため、定番です。
- 版ローテーションは「最新keepGenerations件を残して古い順に削除」。スタンプ名×作成日時で確実に制御します。
- ログは成功・失敗を明記し、後から検証できる形に残します。
シート単位バックアップ:指定シートを新規ブックに保存
シート抜き出し保存テンプレ
' ModBackup_Sheets.bas
Option Explicit
Public Sub BackupSheets(ByVal sheetNames As Variant, ByVal backupRoot As String, Optional ByVal keepGenerations As Long = 10)
Dim tempWB As Workbook
Set tempWB = Application.Workbooks.Add(xlWBATWorksheet)
Dim i As Long
For i = LBound(sheetNames) To UBound(sheetNames)
ThisWorkbook.Worksheets(CStr(sheetNames(i))).Copy After:=tempWB.Worksheets(tempWB.Worksheets.Count)
Next
' 初期シート削除
Application.DisplayAlerts = False
tempWB.Worksheets(1).Delete
Application.DisplayAlerts = True
Dim folder As String: folder = JoinPath(backupRoot, "SheetsBackup")
If Not EnsureFolder(backupRoot) Or Not EnsureFolder(folder) Then
MsgBox "フォルダ作成に失敗: " & folder, vbExclamation: Exit Sub
End If
Dim path As String: path = JoinPath(folder, "Sheets_" & StampNow() & ".xlsx")
tempWB.SaveAs Filename:=path, FileFormat:=xlOpenXMLWorkbook
tempWB.Close SaveChanges:=False
If Not CheckFileExists(path) Or FileSize(path) = 0 Then
AppendLog JoinPath(folder, "backup.log"), "FAILED: " & path
Else
AppendLog JoinPath(folder, "backup.log"), "OK: " & path
Call RotateGenerations folder, ".xlsx", keepGenerations
End If
End Sub
VB重要部分の深掘り
- 大元のブック全体を保存できない運用(機密分離など)では“必要なシートだけ”新規ブックに切り出すのが安全です。
- DisplayAlertsの切替で“シート削除の確認”を無人化。余計なダイアログで止まらないようにします。
CSVエクスポート:テーブルを個別CSVへ、文字化け防止の基本
CSV保存テンプレ
' ModBackup_CSV.bas
Option Explicit
Public Sub ExportTablesToCsv(ByVal wsName As String, ByVal backupRoot As String)
Dim ws As Worksheet: Set ws = Worksheets(wsName)
If ws.ListObjects.Count = 0 Then
MsgBox "テーブルがありません(Ctrl+Tでテーブル化推奨): " & wsName, vbExclamation
Exit Sub
End If
Dim folder As String: folder = JoinPath(backupRoot, "CSV_" & StampNow())
If Not EnsureFolder(backupRoot) Or Not EnsureFolder(folder) Then
MsgBox "フォルダ作成に失敗: " & folder, vbExclamation: Exit Sub
End If
Dim lo As ListObject
For Each lo In ws.ListObjects
Dim tempWB As Workbook: Set tempWB = Application.Workbooks.Add
lo.Range.Copy
tempWB.Worksheets(1).Range("A1").PasteSpecial xlPasteValues
Dim csvPath As String: csvPath = JoinPath(folder, lo.Name & ".csv")
Application.DisplayAlerts = False
tempWB.SaveAs Filename:=csvPath, FileFormat:=xlCSV
Application.DisplayAlerts = True
tempWB.Close False
AppendLog JoinPath(folder, "backup.log"), "CSV: " & csvPath
Next
End Sub
VB重要部分の深掘り
- テーブル(ListObject)単位でCSVにすると、列追加・範囲ズレの事故を防げます。
- CSVは“値貼り付け”で数式を展開して保存。文字化けが懸念される場合は“UTF-8(xlCSVUTF8)”に変更可能です(Excelのバージョン依存)。
圧縮・署名・自動スケジュール(任意拡張)
ZIP圧縮(軽量、標準機能のみ)
' ModBackup_Zip.bas
Option Explicit
Public Sub ZipFolder(ByVal folderPath As String, ByVal zipPath As String)
' WindowsのZIPフォルダ機能を利用(空ZIP作成→シェルコピー)
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(zipPath) Then fso.DeleteFile zipPath, True
Dim f As Integer: f = FreeFile
Open zipPath For Output As #f: Close #f
SetAttr zipPath, vbArchive
Dim sh As Object: Set sh = CreateObject("Shell.Application")
sh.NameSpace(zipPath).CopyHere sh.NameSpace(folderPath).Items
Application.Wait Now + TimeSerial(0, 0, 3) ' 少し待機(大きいフォルダは調整)
End Sub
VB重要部分の深掘り
- ZIPは“シェル経由”でシンプルに圧縮できます。ファイル数が多い場合は待機を伸ばすなど実務調整。
- 署名・ハッシュが必要な現場は、外部ツール連携を想定し、VBA側は「フォルダ構成と名前付け」を厳格にしておくと移行が容易です。
例題の通し方:1クリックで「ブック→シート→CSV→ZIP→ログ」まで
実行例(標準モジュール)
' ModBackup_Example.bas
Option Explicit
Public Sub Run_DailyBackup()
Dim root As String: root = ThisWorkbook.Path & "\Backup"
' 1) ブック全体(7世代)
BackupWorkbook ThisWorkbook, root, 7
' 2) 重要シートのみ(10世代)
Dim sheets As Variant: sheets = Array("Master", "Detail", "Report")
BackupSheets sheets, root, 10
' 3) テーブルをCSVへ
ExportTablesToCsv "Detail", root
' 4) 今日のバックアップフォルダをZIP(任意)
Dim todayFolder As String: todayFolder = JoinPath(root, "CSV_" & StampNow()) ' 実際はCSV作成時のフォルダ名を渡す
Dim zipPath As String: zipPath = JoinPath(root, "Daily_" & StampNow() & ".zip")
' ZipFolder todayFolder, zipPath ' フォルダ名を適宜指定
MsgBox "バックアップが完了しました。", vbInformation
End Sub
VB期待動作の確認ポイント
- Backup\ブック名\yyyy-mm-dd_hhnn.xlsx(またはxlsm)が生成され、backup.logにOKが追記される。
- 指定シートだけのバックアップブックが生成される(SheetsBackup配下)。
- テーブルごとのCSVがフォルダに出力され、ログが残る。
- ZIP圧縮はフォルダ指定で一括圧縮される(任意)。
落とし穴と対策(深掘り)
保存中の編集中断・ダイアログ停止
SaveCopyAsで安全コピーし、DisplayAlertsを適切にOFF/ON。無人実行を前提に“止まらない”設計にします。
フォルダ権限・ネットワーク途切れ
EnsureFolderで失敗時に即時通知。ネットワーク共有先を使う場合は、まずローカルに保存→成功後に共有へコピーの二段構えが安全です。
CSVの文字化け
Excelバージョンに応じて xlCSVUTF8 を選択。必要なら“Unicodeテキスト(.txt)→後処理”の運用も検討。
版管理の誤削除
作成日時ソート+拡張子フィルタで対象を限定。keepGenerationsは環境に合わせて慎重に設定し、初期は多めに残す。
ログが増えすぎて見づらい
1日1ファイルのログ、または月次ログに分割する運用を。ログ行は“日時 | 操作 | パス | 結果”の簡潔な形式に固定します。
まとめ:時刻スタンプ+安全保存+版ローテーション+ログで“壊れない”バックアップ運用にする
- 保存は“安全コピー”で無人化、出力先は時刻スタンプで衝突回避。
- 版数ローテーションで容量を制御し、成功・失敗は必ずログに残す。
- CSV/シート単位/ZIPなど用途別にテンプレを分離し、組み合わせて運用する。

