Excel VBAを使うと、さまざまな自動化タスクを簡単に実行できます。その中でも、ファイル名に日付情報を追加することは、ファイルの整理や管理に非常に役立ちます。本記事では、VBAの基本から具体的なコードの書き方まで、初心者でも分かりやすく解説します。応用例や実践演習も含めて、日付情報を活用したファイル名の自動生成方法をマスターしましょう。
対象はWindows版デスクトップExcelです。保存例は作業用コピーで確認してください。Excel for the webではVBAを実行できません。本文では、名前を組み立てるだけの処理、開いているブックを別名に切り替えるSaveAs、元のブックを開いたまま控えを作るSaveCopyAsを区別します。コードはVBEの「挿入」→「標準モジュール」に記述します。マクロを含むブックは先に.xlsmなどの対応形式で保存してください。
VBAの基本と日付の取得方法
Excel VBA(Visual Basic for Applications)は、Microsoft Excelに組み込まれているプログラミング言語で、タスクの自動化やデータ操作を効率的に行うことができます。ここでは、VBAの基本的な使い方と日付情報を取得する方法について説明します。
VBAの基本的な使い方
Windows版Excelで「開発」タブを表示するには、次の手順を行います。
- Excelを開き、「ファイル」メニューをクリックします。
- 「オプション」を選択します。
- 「リボンのユーザー設定」を選び、「開発」タブにチェックを入れます。
開発タブが表示されたら、次にVBAエディターを開きます。
- 開発タブで「Visual Basic」をクリックします。
- VBAエディターが開きます。
日付情報の取得
VBAでは、日付情報を取得するためにDate関数やNow関数を使用します。
Sub GetDate()
Dim currentDate As Date
currentDate = Date
MsgBox "今日の日付は " & Format$(currentDate, "yyyy-mm-dd")
End Sub
Sub GetDateTime()
Dim currentDateTime As Date
currentDateTime = Now
MsgBox "現在の日付と時刻は " & Format$(currentDateTime, "yyyy-mm-dd hh:nn:ss")
End SubDateは現在の日付、Nowは日付と時刻を返します。どちらも実行環境の時計に基づきます。ファイル名では区切り文字の/や:を避け、Format$で明示的な文字列に変換します。本記事の出力例は通常のグレゴリオ暦設定を前提にしています。
ファイル名に日付を追加するVBAコードの作成
ファイル名に日付情報を追加することで、ファイルのバージョン管理や整理が容易になります。このセクションでは、日付情報をファイル名に追加する具体的なVBAコードを作成します。
基本のVBAコード構成
まずはexample.xlsxから日付付きの名前を組み立てます。これは文字列を表示するだけで、ファイルの作成・名前変更・保存は行いません。
Sub AddDateToFileName()
Dim filePath As String
Dim fileName As String
Dim newFileName As String
Dim currentDate As String
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
filePath = "C:\Users\YourUsername\Documents" ' 実在する保存先に変更
fileName = "example.xlsx"
currentDate = Format$(Date, "yyyymmdd")
newFileName = fso.BuildPath(filePath, _
fso.GetBaseName(fileName) & "_" & currentDate & "." & _
fso.GetExtensionName(fileName))
MsgBox "新しいファイル名は: " & newFileName
End Subコードの詳細説明
このコードの各部分について詳しく説明します。
ファイルパスとファイル名の設定
filePath = "C:\Users\YourUsername\Documents"
fileName = "example.xlsx"この部分では、ファイルの保存先のパスと元のファイル名を設定します。適宜変更してください。
日付情報の取得と形式設定
currentDate = Format$(Date, "yyyymmdd")Format$(Date, "yyyymmdd")で年月日を文字列にします。たとえば2026年10月20日なら20261020です。
新しいファイル名の生成
newFileName = fso.BuildPath(filePath, _
fso.GetBaseName(fileName) & "_" & currentDate & "." & _
fso.GetExtensionName(fileName))GetBaseNameで拡張子を除き、日付を追加してから元の拡張子を戻します。BuildPathは必要なパス区切りを補うため、フォルダー末尾の\の有無に依存しません。この例は拡張子付きの入力を前提にしています。
このコードを実行することで、指定されたファイルパスに基づいて、日付情報が追加された新しいファイル名が生成されます。次に、実際のコード例とその詳細な説明を行います。
実際のコード例とその説明
ここからは実際に保存します。SaveAsは保存後の作業対象を新しいファイル名へ切り替えます。バックアップを作りたいだけならSaveCopyAsを使います。SaveAsでxlOpenXMLWorkbookを指定すると、マクロを保持できない.xlsx形式になります。拡張子の書き換えだけでは正しい形式変換にならないため、保存形式と拡張子を一致させます。
実際のコード例
次の例と、その直後の「共通処理」を同じ標準モジュールへ一度だけ貼り付けます。後半の応用例も共通処理を使用します。Option Explicitはモジュール先頭に一度だけ置き、説明用の抜粋コードは重ねて貼り付けないでください。SaveWorkbookWithDateは別名保存、SaveWorkbookCopyWithDateはコピー保存です。既存のファイル・フォルダーと同名なら上書きせず停止します。
Option Explicit
Sub SaveWorkbookWithDate()
On Error GoTo ErrorHandler
Dim newFileName As String
newFileName = SaveDatedWorkbook(ThisWorkbook, Format$(Date, "yyyymmdd"), False)
MsgBox "別名保存しました: " & newFileName
Exit Sub
ErrorHandler:
MsgBox "保存を完了できませんでした: " & Err.Number & vbCrLf & Err.Description, vbExclamation
End Sub
Sub SaveWorkbookCopyWithDate()
On Error GoTo ErrorHandler
Dim newFileName As String
newFileName = SaveDatedWorkbook(ThisWorkbook, Format$(Date, "yyyymmdd"), True)
MsgBox "コピーを保存しました: " & newFileName
Exit Sub
ErrorHandler:
MsgBox "コピー保存を完了できませんでした: " & Err.Number & vbCrLf & Err.Description, vbExclamation
End Sub共通処理:形式・保存先・同名ファイルを確認する
この共通処理は.xlsx(通常/Strict)、.xlsm、.xlsb、Excel 97–2003形式の.xlsに対象を限定します。テンプレート、アドイン、CSVなどは停止します。SaveCopyAsには形式変換用の引数がないため、コピー時にも元の形式と拡張子を維持します。
Private Function SaveDatedWorkbook(ByVal wb As Workbook, ByVal stamp As String, _
Optional ByVal copyOnly As Boolean = True, _
Optional ByVal folderPath As String = "", _
Optional ByVal baseName As String = "") As String
Dim fso As Object
Dim ext As String
Dim target As String
If wb Is Nothing Then Err.Raise vbObjectError + 2100, , "対象ブックがありません。"
If Len(wb.Path) = 0 Then Err.Raise vbObjectError + 2101, , "先に元ブックを保存してください。"
If Not Application.DisplayAlerts Then
Err.Raise vbObjectError + 2102, , "警告表示が無効です。呼び出し元の設定を確認してください。"
End If
Set fso = CreateObject("Scripting.FileSystemObject")
Select Case wb.FileFormat
Case xlOpenXMLWorkbook, xlOpenXMLStrictWorkbook: ext = "xlsx"
Case xlOpenXMLWorkbookMacroEnabled: ext = "xlsm"
Case xlExcel12: ext = "xlsb"
Case xlExcel8: ext = "xls"
Case Else
Err.Raise vbObjectError + 2103, , "この例では対応していないファイル形式です。"
End Select
If LCase$(fso.GetExtensionName(wb.Name)) <> ext Then
Err.Raise vbObjectError + 2104, , "元ブックの拡張子と形式が一致していません。"
End If
If ext = "xlsx" And wb.HasVBProject Then
Err.Raise vbObjectError + 2105, , "マクロを含むブックは先に.xlsm等で保存してください。"
End If
If Len(folderPath) = 0 Then folderPath = wb.Path
If Len(baseName) = 0 Then baseName = fso.GetBaseName(wb.Name)
If Len(stamp) = 0 Then Err.Raise vbObjectError + 2106, , "日付文字列が空です。"
target = CheckedNewPath(folderPath, baseName & "_" & stamp & "." & ext)
' CheckedNewPathの確認と保存は不可分ではない。同じ名前への並行保存は行わない。
If copyOnly Then
wb.SaveCopyAs Filename:=target
Else
wb.SaveAs Filename:=target, FileFormat:=wb.FileFormat
If StrComp(wb.FullName, target, vbTextCompare) <> 0 Then
Err.Raise vbObjectError + 2107, , "別名保存が完了していません。キャンセルや保存イベントを確認してください。"
End If
End If
If Not fso.FileExists(target) Then
Err.Raise vbObjectError + 2108, , "出力ファイルを確認できません。保存先を確認してください。"
End If
SaveDatedWorkbook = target
End Function
Private Function CheckedFolder(ByVal folderPath As String) As String
Dim fso As Object
If Len(folderPath) = 0 Or InStr(1, folderPath, "://", vbTextCompare) > 0 Then
Err.Raise vbObjectError + 2110, , "実在するローカルまたはUNCフォルダーを指定してください。"
End If
If Left$(folderPath, 4) = "\\?\" Or Left$(folderPath, 4) = "\\.\" Then
Err.Raise vbObjectError + 2111, , "特殊なデバイスパスは対象外です。"
End If
If Not (folderPath Like "[A-Za-z]:\*") And Left$(folderPath, 2) <> "\\" Then
Err.Raise vbObjectError + 2112, , "相対パスではなく完全な保存先を指定してください。"
End If
If InStr(folderPath, "[") > 0 Or InStr(folderPath, "]") > 0 Then
Err.Raise vbObjectError + 2113, , "保存先に角括弧を含めないでください。"
End If
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(folderPath) Then
Err.Raise vbObjectError + 2114, , "保存先フォルダーが見つかりません。"
End If
CheckedFolder = fso.GetFolder(folderPath).Path
End Function
Private Function CheckedNewPath(ByVal folderPath As String, ByVal leafName As String) As String
Dim fso As Object
Dim target As String
CheckFileName leafName
Set fso = CreateObject("Scripting.FileSystemObject")
target = fso.BuildPath(CheckedFolder(folderPath), leafName)
If Len(target) > 218 Then
Err.Raise vbObjectError + 2120, , "フォルダーを含むパスを218文字以内に短くしてください。"
End If
If fso.FileExists(target) Or fso.FolderExists(target) Then
Err.Raise vbObjectError + 2121, , "同名のファイルまたはフォルダーがあります。上書きしません: " & target
End If
CheckedNewPath = target
End Function
Private Sub CheckFileName(ByVal leafName As String)
Dim i As Long
Dim ch As String
Dim deviceName As String
Dim reserved As Boolean
If Len(leafName) = 0 Then Err.Raise vbObjectError + 2130, , "ファイル名が空です。"
If Right$(leafName, 1) = "." Or Right$(leafName, 1) = " " Then
Err.Raise vbObjectError + 2131, , "末尾がピリオドまたは空白の名前は使えません。"
End If
For i = 1 To Len(leafName)
ch = Mid$(leafName, i, 1)
If InStr(1, "\/:*?""<>|[]", ch, vbBinaryCompare) > 0 Or _
(AscW(ch) >= 0 And AscW(ch) < 32) Then
Err.Raise vbObjectError + 2132, , "使用できない文字がファイル名に含まれています。"
End If
Next i
deviceName = UCase$(Trim$(Split(leafName, ".")(0)))
Select Case deviceName
Case "CON", "PRN", "AUX", "NUL": reserved = True
End Select
If Len(deviceName) = 4 Then
If Left$(deviceName, 3) = "COM" Or Left$(deviceName, 3) = "LPT" Then
reserved = InStr(1, "123456789" & ChrW(185) & ChrW(178) & ChrW(179), _
Right$(deviceName, 1), vbBinaryCompare) > 0
End If
End If
If reserved Then Err.Raise vbObjectError + 2133, , "Windowsの予約名は使えません。"
End Sub保存先の確認は、書き込み権限や空き容量、ファイルの完全性まで保証するものではありません。また、存在確認から保存までの間に別の処理が同名ファイルを作る競合は防げません。本例は単一の処理で使い、共有フォルダーへの同時出力では排他制御などを別途設計してください。警告を無効にして強制上書きする実装にはしていません。
コードの詳細説明
1. マクロを含むワークブックを取得
Set wb = ThisWorkbookThisWorkbookは「このマクロが入っているブック」です。画面で前面のブックを意味するActiveWorkbookとは異なります。PERSONAL.XLSBやアドインにコードを置いた場合も、ThisWorkbookはその格納先です。別の作業ブックを対象にするなら、対象を確認してSet wb = Workbooks("対象.xlsm")などで明示的に取得してください。
2. ファイルパスの指定
filePath = wb.Path共通処理では省略時に元ブックのフォルダーを使います。未保存ブックのPathは空文字なので停止します。OneDrive/SharePointのhttps://...などのURLはこのWindowsファイルシステム用コードでは扱わず、同期済みのローカルフォルダーなどを明示します。同期やクラウドへの反映完了は、このコードの成功表示だけでは保証できません。
3. 元のファイル名の取得
fileName = fso.GetBaseName(wb.Name)GetBaseNameで最後の拡張子を除きます。元のLeft(..., InStrRev(...) - 1)だけでは拡張子のない未保存ブックで長さが負になります。共通処理では先に保存済みかどうかと拡張子を検証します。
4. 日付情報の取得と形式設定
currentDate = Format$(Date, "yyyymmdd")Format$(Date, "yyyymmdd")で年月日を文字列にします。たとえば2026年10月20日なら20261020です。
5. 新しいファイル名の生成
target = CheckedNewPath(folderPath, baseName & "_" & stamp & "." & ext)既存ファイルと同じ名前なら停止します。同じ日に複数回コピーするなら、後述の秒付き書式や用途別の接尾辞を使ってください。秒付きでも同じ秒に実行すれば衝突します。SaveAs後に再実行すると、その時点の名前へさらに日付が追加されるので、日々の控えにはコピー保存か固定のbaseNameを使うのが分かりやすくなります。
6. 新しいファイル名でワークブックを保存
wb.SaveAs Filename:=target, FileFormat:=wb.FileFormat
' コピーだけを作る場合は、上の行の代わりに次の行を使う
' wb.SaveCopyAs Filename:=target拡張子だけでなくFileFormatも一致させます。xlOpenXMLWorkbookは.xlsx、xlOpenXMLWorkbookMacroEnabledは.xlsmです。マクロを含む元ブックを.xlsxへ変換しないでください。この抜粋を単独で実行せず、上の検証付き共通処理を使用します。
7. 保存完了メッセージの表示
MsgBox "別名保存しました: " & newFileNameメッセージボックスで、新しいファイル名をユーザーに通知します。
別名保存とコピー保存の違いを確認してから実行します。共通処理はブックの保存を行いますが、ファイルを削除したり、開いている元ブックを閉じたりはしません。
エラー処理とデバッグの方法
VBAコードを実行する際、予期せぬエラーが発生することがあります。エラーが発生した場合に適切に対処し、コードのデバッグを行うことで、スムーズに作業を進めることができます。このセクションでは、エラー処理とデバッグの方法について詳しく説明します。
エラー処理の追加
上の例にはすでにエラー処理を含めています。次は、別の保存先を指定してコピーを作る呼び出し例です。共通処理も同じ標準モジュールに必要です。
Sub SaveWorkbookWithDateHandled()
On Error GoTo ErrorHandler
Dim newFileName As String
newFileName = SaveDatedWorkbook(ThisWorkbook, Format$(Date, "yyyymmdd"), _
True, "C:\Users\YourUsername\Documents")
MsgBox "コピーを保存しました: " & newFileName
Exit Sub
ErrorHandler:
MsgBox "処理を完了できませんでした: " & Err.Number & vbCrLf & Err.Description, vbExclamation
End Subエラー処理の詳細
1. エラーハンドラの設定
On Error GoTo ErrorHandlerこの行で、エラーが発生した場合にErrorHandlerラベルにジャンプするよう設定します。
2. エラーメッセージの表示
ErrorHandler:
MsgBox "処理を完了できませんでした: " & Err.Number & vbCrLf & Err.Description, vbExclamationErr.NumberとErr.Descriptionを確認します。エラー後にファイルが一部作成されている可能性もあるため、同名の出力を確認せずに再実行・削除・上書きしないでください。保存例はDisplayAlerts=Falseを使いません。Excelでは警告を無効にしたSaveAsが既存ファイルを上書きすることがあります。
デバッグの方法
ブレークポイントの設定
コード行の左側の余白をクリックするか、実行可能な行へカーソルを置いてF9キーを押すとブレークポイントを設定できます。保存の行に到達する前に、対象ブックと出力パスを確認してください。
ステップ実行
F8キーで一行ずつ実行できます。ただし、保存の行まで進めれば実際にファイルが書き込まれます。事前にVBEの「デバッグ」→「VBAProjectのコンパイル」も行い、作業用コピーで確認します。型の宣言はDim newFileName As StringのようにAsを使います。
ウォッチウィンドウの使用
ウォッチウィンドウを使用して、特定の変数の値を監視することができます。ウォッチウィンドウに変数を追加するには、変数を右クリックして「ウォッチの追加」を選択します。これにより、変数の値が変更されるたびにその値を確認できます。
これらのエラー処理とデバッグの方法を使用することで、VBAコードの問題を迅速に特定し、修正することができます。次に、異なる日付形式のファイル名の生成方法について解説します。
応用例:異なる日付形式のファイル名
日付情報をファイル名に追加する際、さまざまな日付形式を使用することができます。このセクションでは、異なる日付形式を使用したファイル名の生成方法を紹介します。
異なる日付形式の例
日付情報は、以下のようなさまざまな形式で表示できます。
yyyymmdd→ 20261020yyyy-mm-dd→ 2026-10-20yyyymmdd_hhnnss→ 20261020_143507yyyy_mm_dd_hh_nn_ss→ 2026_10_20_14_35_07
時刻の出力例は2026年10月20日14時35分7秒を想定しています。以下は共通処理を使ったコピー保存の例です。
例1: yyyy-mm-dd形式
Sub SaveWorkbookWithFormattedDate1()
On Error GoTo ErrorHandler
Dim newFileName As String
newFileName = SaveDatedWorkbook(ThisWorkbook, Format$(Date, "yyyy-mm-dd"), True)
MsgBox "コピーを保存しました: " & newFileName
Exit Sub
ErrorHandler:
MsgBox Err.Number & vbCrLf & Err.Description, vbExclamation
End Sub例2: yyyymmdd_hhnnss形式
Sub SaveWorkbookWithFormattedDate2()
On Error GoTo ErrorHandler
Dim newFileName As String
newFileName = SaveDatedWorkbook(ThisWorkbook, Format$(Now, "yyyymmdd_hhnnss"), True)
MsgBox "コピーを保存しました: " & newFileName
Exit Sub
ErrorHandler:
MsgBox Err.Number & vbCrLf & Err.Description, vbExclamation
End Sub例3: yyyy_mm_dd_hh_nn_ss形式
Sub SaveWorkbookWithFormattedDate3()
On Error GoTo ErrorHandler
Dim newFileName As String
newFileName = SaveDatedWorkbook(ThisWorkbook, Format$(Now, "yyyy_mm_dd_hh_nn_ss"), True)
MsgBox "コピーを保存しました: " & newFileName
Exit Sub
ErrorHandler:
MsgBox Err.Number & vbCrLf & Err.Description, vbExclamation
End SubVBAの分はnnで指定すると明確です。mmは通常「月」で、h/hhに続く場合に分として解釈されるため、時刻にはhhnnssまたはhh_nn_ssを使います。日付を二度取得せず、一つのNow値を書式化すれば、日付と時刻の境界をまたいで組み合わせることも避けられます。
次に、学んだ内容を元に、日付情報を追加したファイルを自動で生成する実践演習を行います。
実践演習:日付情報を追加したファイルの自動生成
ここでは、これまでに学んだ内容を活用して、日付情報を追加したファイルを自動で生成する実践演習を行います。具体的なシナリオを設定し、そのシナリオに基づいてVBAコードを作成します。
シナリオ
毎日業務終了後に、「SalesData」ワークシートだけを別ブックにしてSalesData_yyyymmdd.xlsxという名前で保存します。元ブック全体を保存する処理とは区別します。シートにVBAコードがある場合は、マクロを黙って削除せず停止する例です。
VBAコードの作成
上の共通処理と同じ標準モジュールで使用します。Worksheet.Copyで作ったブックだけを保存し、元ブックにはSaveAsしません。数式もコピーされるため、他シートや他ブックへの参照は外部リンクになる場合があります。確定値だけの帳票が必要なら、別途値のみの出力を設計してください。
Sub SaveSalesDataWithDate()
Dim sourceWb As Workbook
Dim exportWb As Workbook
Dim ws As Worksheet
Dim fso As Object
Dim newFileName As String
Dim oldEvents As Boolean
Dim stateCaptured As Boolean
Dim failureNumber As Long
Dim failureText As String
Dim cleanupText As String
Dim saved As Boolean
On Error GoTo ErrorHandler
Set sourceWb = ThisWorkbook
Set ws = sourceWb.Worksheets("SalesData")
Set fso = CreateObject("Scripting.FileSystemObject")
If Not Application.DisplayAlerts Then
Err.Raise vbObjectError + 2140, , "警告表示が無効です。呼び出し元の設定を確認してください。"
End If
newFileName = CheckedNewPath(sourceWb.Path, _
"SalesData_" & Format$(Date, "yyyymmdd") & ".xlsx")
oldEvents = Application.EnableEvents
stateCaptured = True
Application.EnableEvents = False
ws.Copy
Set exportWb = ActiveWorkbook ' Copy直後の新しいブックだけを保持
If exportWb Is sourceWb Then Err.Raise vbObjectError + 2141, , "出力ブックを取得できません。"
If exportWb.HasVBProject Then
Err.Raise vbObjectError + 2142, , "シートのVBAコードがあるため.xlsxへ変換しません。"
End If
If fso.FileExists(newFileName) Or fso.FolderExists(newFileName) Then
Err.Raise vbObjectError + 2143, , "同名の出力ができたため保存を中止します。"
End If
exportWb.SaveAs Filename:=newFileName, FileFormat:=xlOpenXMLWorkbook
If StrComp(exportWb.FullName, newFileName, vbTextCompare) <> 0 Or _
Not fso.FileExists(newFileName) Then
Err.Raise vbObjectError + 2144, , "保存完了を確認できません。"
End If
saved = True
GoTo CleanUp
ErrorHandler:
failureNumber = Err.Number
failureText = Err.Description
Resume CleanUp
CleanUp:
On Error Resume Next
If Not exportWb Is Nothing Then
If Not exportWb Is sourceWb Then exportWb.Close SaveChanges:=False
End If
If Err.Number <> 0 Then cleanupText = "出力ブックを閉じられません: " & Err.Description
Err.Clear
If stateCaptured Then Application.EnableEvents = oldEvents
If Err.Number <> 0 Then cleanupText = cleanupText & vbCrLf & "イベント設定を復元できません: " & Err.Description
On Error GoTo 0
If failureNumber <> 0 Then
MsgBox "処理を完了できませんでした: " & failureNumber & vbCrLf & failureText & _
vbCrLf & "出力ファイルがある場合は内容を確認してください。" & vbCrLf & cleanupText, vbExclamation
ElseIf Len(cleanupText) > 0 Then
MsgBox "保存後の後処理を確認してください: " & newFileName & vbCrLf & cleanupText, vbExclamation
ElseIf saved Then
MsgBox "売上シートを保存しました: " & newFileName
End If
End Subコードの詳細説明
1. シートの指定
Set ws = sourceWb.Worksheets("SalesData")「SalesData」というワークシートを明示します。Set ws = ...だけではそのシートだけの保存にはなりません。ws.Copyで新しいブックを作り、直後のActiveWorkbookを保持して、そちらを保存します。
2. ファイルパスとファイル名の設定
newFileName = CheckedNewPath(sourceWb.Path, _
"SalesData_" & Format$(Date, "yyyymmdd") & ".xlsx")元ブックと同じフォルダーへ出力します。未保存やURL形式の保存先は共通処理で停止します。別の場所ならsourceWb.Pathを実在するWindowsの完全なフォルダーパスへ変更してください。
3. 日付情報の取得と形式設定
currentDate = Format$(Date, "yyyymmdd")Format$(Date, "yyyymmdd")で年月日を文字列にします。たとえば2026年10月20日なら20261020です。
4. 新しいファイル名の生成
"SalesData_" & Format$(Date, "yyyymmdd") & ".xlsx"固定の接頭辞に日付を加えます。同日分がすでにあれば停止するため、保存済み帳票を意図せず上書きしません。
5. 新しいファイル名でワークブックを保存
exportWb.SaveAs Filename:=newFileName, FileFormat:=xlOpenXMLWorkbook出力用ブックにVBAプロジェクトがないことを確認してから.xlsxとして保存します。Worksheet.Copyはシートのコードも引き継ぐため、マクロがあるシートはこの例では停止します。元ブックのマクロは削除しません。
6. 保存完了メッセージの表示
MsgBox "売上シートを保存しました: " & newFileName保存の確認と後処理が終わってから通知します。成功・失敗のどちらでも出力用ブックだけを閉じ、変更したEnableEventsを元の値へ戻します。途中で生成されたファイルは自動削除しません。
この実践演習を通して、日付情報を追加したファイルの自動生成方法を習得できます。次に、日付情報をファイル名に追加する際によくある質問とその解決方法について解説します。
よくある質問とその解決方法
日付情報をファイル名に追加する際、よくある質問とその解決方法をまとめます。これにより、よく発生する問題を事前に解決し、スムーズに作業を進めることができます。
質問1: 保存先のフォルダが存在しない場合はどうすればよいですか?
親フォルダーが存在することを確認してから、一段だけ子フォルダーを作成します。CreateFolderは不足した中間フォルダーをまとめて作る処理ではありません。次の例は元ブックの場所に「SalesData」フォルダーを作り、ブック全体のコピーを元の拡張子のまま保存します。
Sub SaveWorkbookWithDateAndFolderCheck()
On Error GoTo ErrorHandler
Dim fso As Object
Dim parentPath As String
Dim folderPath As String
Dim newFileName As String
Set fso = CreateObject("Scripting.FileSystemObject")
parentPath = CheckedFolder(ThisWorkbook.Path)
folderPath = fso.BuildPath(parentPath, "SalesData")
If fso.FileExists(folderPath) Then
Err.Raise vbObjectError + 2150, , "SalesDataという同名ファイルがあるためフォルダーを作れません。"
End If
If Not fso.FolderExists(folderPath) Then fso.CreateFolder folderPath
newFileName = SaveDatedWorkbook(ThisWorkbook, Format$(Date, "yyyymmdd"), _
True, folderPath, "SalesData")
MsgBox "コピーを保存しました: " & newFileName
Exit Sub
ErrorHandler:
MsgBox Err.Number & vbCrLf & Err.Description, vbExclamation
End Sub質問2: ファイル名に使用できない文字が含まれている場合はどうすればよいですか?
Windowsでは\ / : * ? " < > |、制御文字、予約名、末尾の空白・ピリオドなどを確認します。Excelで問題になり得る角括弧も避けます。共通処理のCheckFileNameは不正な名前を拒否します。ユーザー入力の接頭辞を整える場合は、次の補助関数で文字を除去した後、空文字になっていないかと最終ファイル名を再検証します。フォルダーパス全体には適用しないでください。
Private Function RemoveInvalidCharacters(ByVal fileName As String) As String
Dim invalidChars As String
Dim i As Long
invalidChars = "\/:*?""<>|[]"
For i = 1 To Len(invalidChars)
fileName = Replace(fileName, Mid$(invalidChars, i, 1), "")
Next i
For i = 0 To 31
fileName = Replace(fileName, Chr$(i), "")
Next i
fileName = Trim$(fileName)
Do While Len(fileName) > 0
If Right$(fileName, 1) <> "." And Right$(fileName, 1) <> " " Then Exit Do
fileName = Left$(fileName, Len(fileName) - 1)
Loop
If Len(fileName) = 0 Then Err.Raise vbObjectError + 2160, , "有効な名前を入力してください。"
CheckFileName fileName
RemoveInvalidCharacters = fileName
End Function自動除去すると別々の入力が同じ名前になることがあります。たとえばA/BとA:Bは両方ABになります。保存時の同名チェックを省略しないでください。予約名などを無理に自動修正せず、入力の変更を求めます。
Sub SaveWorkbookWithCleanFileName()
On Error GoTo ErrorHandler
Dim fileName As String
Dim newFileName As String
fileName = RemoveInvalidCharacters("Sales:Data")
newFileName = SaveDatedWorkbook(ThisWorkbook, Format$(Date, "yyyymmdd"), _
True, "", fileName)
MsgBox "コピーを保存しました: " & newFileName
Exit Sub
ErrorHandler:
MsgBox Err.Number & vbCrLf & Err.Description, vbExclamation
End Sub質問3: 他のプログラムがファイルを使用中で保存できない場合はどうすればよいですか?
保存失敗はロックだけでなく、権限不足、空き容量、同期、無効なパスなどでも起きます。すべてを「使用中」と決めつけて自動再試行しないでください。次の例はエラーを表示して再試行するかを利用者に確認し、合計3回までコピー保存を試します。各回で保存先を再確認し、同名の出力があれば上書きせず停止します。
Sub SaveWorkbookWithRetry()
On Error GoTo ErrorHandler
Dim attempt As Long
Dim stamp As String
Dim newFileName As String
Dim errorNumber As Long
Dim errorText As String
stamp = Format$(Now, "yyyymmdd_hhnnss")
For attempt = 1 To 3
Err.Clear
On Error Resume Next ' 保存呼び出しだけに限定
newFileName = SaveDatedWorkbook(ThisWorkbook, stamp, True)
errorNumber = Err.Number
errorText = Err.Description
On Error GoTo ErrorHandler
If errorNumber = 0 Then
MsgBox "コピーを保存しました: " & newFileName
Exit Sub
End If
If errorNumber = vbObjectError + 2121 Or attempt = 3 Then
MsgBox "再試行を停止します: " & errorNumber & vbCrLf & errorText, vbExclamation
Exit Sub
End If
If MsgBox("保存を完了できません: " & errorNumber & vbCrLf & errorText & _
vbCrLf & "保存先と原因を確認してから再試行しますか?", _
vbRetryCancel + vbExclamation) <> vbRetry Then Exit Sub
Next attempt
Exit Sub
ErrorHandler:
MsgBox Err.Number & vbCrLf & Err.Description, vbExclamation
End Subこれらの解決方法を活用することで、よくある問題を解決し、VBAコードをより堅牢にすることができます。次に、この記事のまとめを行います。
まとめ
ファイル名に日付を付ける基本はFormat$(Date, "yyyymmdd")です。時分秒まで付けるならFormat$(Now, "yyyymmdd_hhnnss")とし、分をnnで指定します。名前の生成と実際の保存は別の処理です。
実際の保存では、対象ブック、保存方法、ファイル形式と拡張子、保存先、同名ファイルを確認します。日々のバックアップにはSaveCopyAs、新しい名前で作業を続けるときはSaveAsを選び、マクロを含むブックを不用意に.xlsxへ変換しないようにしましょう。
このページのコードは説明用です。本改訂ではExcel上の実行検証は行っていません。初回は不要なデータを含まない作業用ブックで、未保存・同名・マクロ付き・保存不可などのケースを確認してください。
参考資料(Microsoft公式)
Workbook.SaveAs / Workbook.SaveCopyAs / ThisWorkbook / ActiveWorkbook / Format関数 / XlFileFormat / Worksheet.Copy / DisplayAlerts / Windowsのファイル名規則 / Excelのファイル名・パス制限


コメント