こんにちは。業務自動化の世界へようこそ。
Excelでレポートを作成し、それをそのままメールで送る。この一連の流れを自動化するのは、業務効率化の「最初の聖域」です。
しかし、多くの初心者がここで必ず壁にぶつかります。それが「ファイルが使用中です」というエラーです。
今日は、なぜそのエラーが起きるのか、そしてプロとしてどう解決するのか。Outlook VBAの根幹を成すオブジェクトモデルの話を交えながら、その「極意」を授けます。
—
1. なぜ「ファイルがロック」されるのか?
Excelで`SaveAs`(名前を付けて保存)を実行した直後、私たちは即座にOutlookの`Attachments.Add`メソッドを呼び出そうとします。
ここで起きているのは「Windows OSの処理の遅延」です。Excelが「保存しました」と報告しても、OS側ではまだファイルハンドルを掴んだまま、データの書き込みやインデックス更新を行っている最中なのです。この「空白の数ミリ秒」にOutlookがアクセスしに行こうとするから、弾かれる。これがエラーの正体です。
2. 解決の要:Sessionとオブジェクトのライフサイクル
まずは、基本のコード構成を見てみましょう。Outlookを操作する際、必ず意識すべきは「Session(NameSpace)」の存在です。
Sub SendReportWithAttachment()
Dim olApp As Object ‘ Outlook.Application
Dim olNs As Object ‘ Outlook.NameSpace
Dim olMail As Object ‘ Outlook.MailItem
Dim filePath As String
‘ 1. Outlookのセッションを掌握する
Set olApp = CreateObject(“Outlook.Application”)
Set olNs = olApp.GetNamespace(“MAPI”)
olNs.Logon ‘ セッションの確立を確認
filePath = “C:\Reports\MonthlyReport.xlsx”
‘ 2. メールアイテムの生成
Set olMail = olApp.CreateItem(0) ‘ 0 = olMailItem
‘ — ここでファイルを添付する —
‘ ファイルの準備が整うまで待機する関数を挟むのがプロの流儀
If WaitForFileAccess(filePath) Then
olMail.Attachments.Add filePath
olMail.Display ‘ 送信前に確認するのが鉄則
Else
MsgBox “ファイルがまだロックされています。処理を中断します。”
Exit Sub
End If
End Sub
3. 【奥義】ファイルロック回避の待機処理
単なる`Sleep`(一時停止)は素人のやり方です。処理が終わっているなら1msでも早く進めるべきですし、終わっていないなら確実に待つ。これが「堅牢な自動化」です。
ファイルがアクセス可能かどうかを判定する、最も確実な手法は「排他制御を試みる」ことです。
‘ ファイルが解放されるまで最大10秒間待機する関数
Function WaitForFileAccess(filePath As String) As Boolean
Dim fileNum As Integer
Dim i As Integer
On Error Resume Next ‘ エラーを無視して試行する
For i = 1 To 20 ‘ 0.5秒間隔で20回(計10秒)試行
fileNum = FreeFile
Open filePath For Input Lock Read Write As #fileNum
Close #fileNum
If Err.Number = 0 Then
WaitForFileAccess = True
Exit Function
End If
Err.Clear
Application.Wait (Now + TimeValue(“0:00:00.5”)) ‘ 0.5秒待機
Next i
WaitForFileAccess = False ‘ 10秒経ってもダメなら諦める
End Function
このコードの「賢い」ポイント
- `Open … Lock Read Write`: これが肝です。実際にファイルを開こうとすることで、OSが本当にそのファイルへのアクセス権を許可しているかを確認しています。
- `FreeFile`: 空いているファイル番号を動的に取得します。ハードコーディングは避けましょう。
- `On Error Resume Next`: エラーを「異常」ではなく「状態確認のフラグ」として利用しています。
—
4. プロの現場で生き残るための心得
初心者がやりがちな「とりあえず`Sleep 2000`(2秒待機)を入れておけ」というコードは、PCのスペックやネットワーク環境の変化に極めて脆弱です。
- 遅いPCなら失敗する
- 速いPCなら2秒間無駄に待たされる
今回紹介した「試行型待機(ポーリング)」を採用することで、「環境に依存せず、かつ最速で完了する」というエンジニアリングの理想を実現できます。
まとめ:次に進むために
1. ApplicationとNameSpace(Session)を正しく理解する。 これがOutlook VBAの入り口です。
2. 外部ファイル操作は「試行」で待つ。 `Sleep`で祈る時代はもう終わりです。
3. オブジェクトの解放を忘れない。 `Set olMail = Nothing` などを最後に入れることで、メモリリークを防ぎ、Excelの動作を軽快に保てます。
ここをクリアすれば、あなたはもう「マクロを記録する人」ではありません。「業務の仕組みを創るエンジニア」です。一歩ずつ、その階段を登っていきましょう。応援しています。
