業務効率化

OutlookVBA:メール送信キャンセル

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関数を冒頭で宣言し使用しています。

WindowsAPI関数

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

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進
EscvbKeyEscape27
EntervbKeyReturn13
SpacevbKeySpace32
TabvbKeyTab9
BackSpacevbKeyBack8
ShiftvbKeyShift16
CtrlvbKeyControl17
AltvbKeyMenu18
CapsLockvbKeyCapital20

編集・移動系

キーVBA定数10進
InsertvbKeyInsert45
DeletevbKeyDelete46
HomevbKeyHome36
EndvbKeyEnd35
PageUpvbKeyPageUp33
PageDownvbKeyPageDown34

矢印キー

キーVBA定数10進
←vbKeyLeft37
↑vbKeyUp38
→vbKeyRight39
↓vbKeyDown40

ファンクションキー

キー定数10進
F1vbKeyF1112
F2vbKeyF2113
F3vbKeyF3114
F4vbKeyF4115
F5vbKeyF5116
F6vbKeyF6117
F7vbKeyF7118
F8vbKeyF8119
F9vbKeyF9120
F10vbKeyF10121
F11vbKeyF11122
F12vbKeyF12123

アルファベット・数字キー

・A~Z・・・A = 65 ~ Z = 90

・0~9(上段)0 = 48 ~ 9 = 57

テンキー(NumPad)

キー10進
Num096
Num197
Num298
Num399
Num4100
Num5101
Num6102
Num7103
Num8104
Num9105
Num*106
Num+107
Num-109
Num.110
Num/111

-業務効率化