Outlook Classicで送信ボタン押下後キャンセル可能にするマクロです。ウィンドウを表示してキャンセル押したらキャンセルのように可視化した送信遅延も可能ですが、今回は1プロシージャだけコピペすれば動作遅延できるように,何かキーが押された場合をキャンセルとしています。
・挙動
メール送信クリック語5秒間の間に特殊キー(Escやスペースキーなど今回指定したキー)を押すことで送信をキャンセルできます。ボタンを押すと変更を保存するかどうかが表示されます。
指定しているキーは下記でスクリプト変更により条件増減可能です。送信を押し5秒以内に下記キーが送信されると送信がキャンセルされます。
| 27, ' Esc |
| 13, ' Enter |
| 32, ' Space |
| 9, ' Tab |
| 8, ' BackSpace |
| 46, ' Delete |
| 45, ' Insert |
| 36, ' Home |
| 35, ' End |
| 33, ' PageUp |
| 34 ' PageDown |
・コード
OutlookでAlt+F11を押し、VBE画面を開きます。そこのThisOutlookSessionに下記スクリプトを貼り付けてください。

➤コードはこちら
Option Explicit
Private Declare PtrSafe Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim i As Long, k As Variant
Dim sec As Long
Dim cancelKeys As Variant
' ===== キャンセル対象キー一覧 =====
cancelKeys = Array(27, 13, 32, 9, 8, 46, 45, 36, 35, 33, 34)
' ===== ① 送信操作で押されたキーが「完全に離される」まで待つ =====
Do
DoEvents
Sleep 50
Loop While IsAnyKeyPressed(cancelKeys)
' ===== ② カウントダウン & キー監視(5秒) =====
For i = 50 To 1 Step -1
DoEvents
Sleep 100
sec = (i + 9) \ 10
If IsAnyKeyPressed(cancelKeys) Then
Cancel = True
On Error Resume Next
Item.Save
On Error GoTo 0
MsgBox "特殊キーが押されたため送信をキャンセルしました。" & vbCrLf & _
"内容は下書きに保存されています。", vbExclamation
Exit Sub
End If
Next i
End Sub
Private Function IsAnyKeyPressed(keyArray As Variant) As Boolean
Dim k As Variant
For Each k In keyArray
' ★ 押された瞬間も確実に拾う版
If GetAsyncKeyState(k) <> 0 Then
IsAnyKeyPressed = True
Exit Function
End If
Next
End Function
・ポイント機能
・5秒間待機とキー送信によるキャンセル
・Windowsの「仮想キーコード(Virtual-Key Codes, VK)」
5秒間待機とキー送信によるキャンセル
スクリプトではボタン送信情報によりループ処理でSleepし、待機しています。キーボードの送信情報と待機する際は、WindowsAPIの関数が便利なため、SleepとGetAsyncKeyState関数を冒頭で宣言し使用しています。

キャンセル対象のボタンはそれぞれ数値が割り当てられており、指定可能です。今回は下記の通り指定しており、一つが押されればキャンセルされます。

| 27, ' Esc |
| 13, ' Enter |
| 32, ' Space |
| 9, ' Tab |
| 8, ' BackSpace |
| 46, ' Delete |
| 45, ' Insert |
| 36, ' Home |
| 35, ' End |
| 33, ' PageUp |
| 34 ' PageDown |
ループ中にボタンが押された場合はループを抜け、変数の判断のもとでキャンセルされます。
スクリプトでキャンセルされた場合はメッセージボックスが表示されるようにしています。ただこの処理は動作する場合としない場合があります。キー送信情報のかち合いがあるためいつも動作するわけではありません。

なお、New Outlookのように送信遅延を可視化はしていません。送信遅延をウィンドウで示して実現する場合は、標準プロシージャとユーザーフォームを作成することで、キャンセルボタンが押されない場合は自動送信というような送信遅延も実現可能です。
Windowsの「仮想キーコード(Virtual-Key Codes, VK)」
GetAsyncKeyStateで指定できるキーボードのコードはそれぞれ数値等で指定可能です。上記スクリプトでは一部特殊キーを指定しています。さらにキャンセル対象のキー範囲を広げる際は関数に対応の番号を指定します。
下記に代表キーボードそれぞれに対する番号を記載します。
制御キー系
| キー | VBA定数 | 10進 |
|---|---|---|
| Esc | vbKeyEscape | 27 |
| Enter | vbKeyReturn | 13 |
| Space | vbKeySpace | 32 |
| Tab | vbKeyTab | 9 |
| BackSpace | vbKeyBack | 8 |
| Shift | vbKeyShift | 16 |
| Ctrl | vbKeyControl | 17 |
| Alt | vbKeyMenu | 18 |
| CapsLock | vbKeyCapital | 20 |
編集・移動系
| キー | VBA定数 | 10進 |
|---|---|---|
| Insert | vbKeyInsert | 45 |
| Delete | vbKeyDelete | 46 |
| Home | vbKeyHome | 36 |
| End | vbKeyEnd | 35 |
| PageUp | vbKeyPageUp | 33 |
| PageDown | vbKeyPageDown | 34 |
矢印キー
| キー | VBA定数 | 10進 |
|---|---|---|
| ← | vbKeyLeft | 37 |
| ↑ | vbKeyUp | 38 |
| → | vbKeyRight | 39 |
| ↓ | vbKeyDown | 40 |
ファンクションキー
| キー | 定数 | 10進 |
|---|---|---|
| F1 | vbKeyF1 | 112 |
| F2 | vbKeyF2 | 113 |
| F3 | vbKeyF3 | 114 |
| F4 | vbKeyF4 | 115 |
| F5 | vbKeyF5 | 116 |
| F6 | vbKeyF6 | 117 |
| F7 | vbKeyF7 | 118 |
| F8 | vbKeyF8 | 119 |
| F9 | vbKeyF9 | 120 |
| F10 | vbKeyF10 | 121 |
| F11 | vbKeyF11 | 122 |
| F12 | vbKeyF12 | 123 |
アルファベット・数字キー
・A~Z・・・A = 65 ~ Z = 90
・0~9(上段)0 = 48 ~ 9 = 57
テンキー(NumPad)
| キー | 10進 |
|---|---|
| Num0 | 96 |
| Num1 | 97 |
| Num2 | 98 |
| Num3 | 99 |
| Num4 | 100 |
| Num5 | 101 |
| Num6 | 102 |
| Num7 | 103 |
| Num8 | 104 |
| Num9 | 105 |
| Num* | 106 |
| Num+ | 107 |
| Num- | 109 |
| Num. | 110 |
| Num/ | 111 |