ショートカットキー一覧を表示するユーザーフォーム【ExcelVBA】

## 目的
ショートカットキーもりもりのブック（特に他人がつくったもの）のショートカットをヘルプ的にパッと呼び出したい。

そのブックに仕込めれば仕込むもよし、アドインで別持ちしておくもよし。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/f61b1ba0-a254-2a3a-f108-285b7a425d6f.png)

VBE内を巡回してショートカットを割り当ててるところを読み込みにいくようなことも上級者ならできるんだろうけど、できないのでやってない。我こそはという猛者によるアップグレード版待ってます。

## 概要
1. Ctrl+Shft+?でユーザーフォームを表示
1. すでに表示中にCtrl+Shft+?を押すとユーザーフォームを閉じる
1. 表示位置は右下（デフォルトだと左上とか中央になるけどまあ邪魔なんで）
1. アイテム数が多いとアイテム数に合わせて縦に長くなるのでお好みで上限を設けてスクロールして

以下作り方

## ユーザーフォーム

オブジェクト名は以下の通り
- uf_ショートカットキー一覧表示_
- lv_ショートカットキー一覧
- CommandButton1

サイズは適当でいい。動的に変更するので。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/9c5b4366-dd24-d980-1f20-f70758f3e4d8.png)

ユーザーフォーム表示中にExcelを普通に操作できるようにしておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/d8cd4638-65c7-d4e2-407f-a4368166fa08.png)

ユーザーフォームフォーカス中にEscで閉じたい人用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/05d07d01-7675-fc5f-ee72-8cb8f227c18b.png)




## コード
### ThisWorkbook
``` vb
Private Sub Workbook_Open()
  Application.OnKey "^+?", "ShowUF_ショートカットキー一覧表示"
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
  Application.OnKey "^+?"
End Sub
```

### 標準モジュール
``` vb
Option Explicit
Private Declare PtrSafe Function SetFocus Lib "user32" (ByVal hwnd As LongLong) As LongLong

Sub ShowUF_ショートカットキー一覧表示()
  With uf_ショートカットキー一覧表示_
    If .Visible = False Then
      .Show
    Else
      ' 表示状態なら閉じる
      Unload uf_ショートカットキー一覧表示_
    End If
  End With
  SetFocus app.hwnd
End Sub

Function app() As Application
  Set app = Application
End Function

```


### ユーザーフォーム
`Const h_ListItem行の高さ = 15`は要調整かも。
`sb_ListView列幅設定`内の各列幅の値も要調整。

``` vb
Option Explicit

Const h_ListItem行の高さ = 15

Private Sub CommandButton1_Click()
  Unload Me
End Sub

Private Sub UserForm_Initialize()
  
  Call sb_ListView初期化(lv_ショートカットキー一覧)
  Call sb_ListViewアイテム登録(lv_ショートカットキー一覧)
  Call sb_lvサイズ調整(lv_ショートカットキー一覧)
  
  Call sb_UFサイズ調整
  Call sb_UF初期位置を右下に
  
End Sub

Private Sub sb_ListViewアイテム登録(myLV As ListView)
    With myLV.ListItems.Add: .Text = "Ctrl＋": .SubItems(1) = "Q": .SubItems(2) = "機能１": End With
    With myLV.ListItems.Add: .Text = "Ctrl＋Shift＋": .SubItems(1) = "Q": .SubItems(2) = "機能２": End With
    With myLV.ListItems.Add: .Text = "Ctrl＋Alt＋Shift＋": .SubItems(1) = "Q": .SubItems(2) = "機能３": End With
    With myLV.ListItems.Add: .Text = "Ctrl＋": .SubItems(1) = "W": .SubItems(2) = "機能４": End With
    With myLV.ListItems.Add: .Text = "Ctrl＋Alt＋Shift＋": .SubItems(1) = "P": .SubItems(2) = "機能５": End With
    With myLV.ListItems.Add: .Text = "Ctrl＋Alt＋Shift＋": .SubItems(1) = "A": .SubItems(2) = "機能６": End With
    With myLV.ListItems.Add: .Text = "Ctrl＋Alt＋Shift＋": .SubItems(1) = "D": .SubItems(2) = "機能７": End With
    With myLV.ListItems.Add: .Text = "Ctrl＋Alt＋Shift＋": .SubItems(1) = "X": .SubItems(2) = "機能８": End With
    With myLV.ListItems.Add: .Text = "Ctrl＋Alt＋Shift＋": .SubItems(1) = "F": .SubItems(2) = "機能９": End With
    With myLV.ListItems.Add: .Text = "Ctrl＋Alt＋Shift＋": .SubItems(1) = "K": .SubItems(2) = "機能１０": End With
End Sub

Private Sub sb_ListView初期化(myLV As ListView)
  With myLV
    .View = lvwReport
    .LabelEdit = lvwManual
    .HideSelection = False
    .AllowColumnReorder = True
    .FullRowSelect = True
    .Gridlines = True
    .ColumnHeaders.Add , "_key1", "Key1"
    .ColumnHeaders.Add , "_key2", "Key2"
    .ColumnHeaders.Add , "_func", "機能"
  End With

End Sub

Private Function sb_ListView列幅設定(myLV As ListView) As Long
  Const c1 = 100
  Const c2 = 30
  Const c3 = 180
  With myLV
    .ColumnHeaders(1).Width = c1
    .ColumnHeaders(2).Width = c2
    .ColumnHeaders(3).Width = c3
  End With
  sb_ListView列幅設定 = c1 + c2 + c3
End Function

Private Sub sb_UF初期位置を右下に()
  With Me
    .StartUpPosition = 0
    .Top = app.Top + app.Height - .Height - 4
    .Left = app.Left + app.Width - .Width - 4
  End With
End Sub

Private Sub sb_UFサイズ調整()
  Me.Width = lv_ショートカットキー一覧.Width + 10
  Me.Height = lv_ショートカットキー一覧.Height + 15
End Sub

Private Sub sb_lvサイズ調整(myLV As ListView)
  With myLV
    .Width = sb_ListView列幅設定(lv_ショートカットキー一覧)
    .Height = .ListItems.Count * h_ListItem行の高さ
  End With

End Sub

```

## コード作成補助（ワークシート関数）

`sb_ListViewアイテム登録`内を書いていくのがまあ面倒なんでワークシート関数で文字列結合とか接頭語とかいろいろサポートしてもらう。Excelは表計算ソフトであると同時にテキストエディターでもあります。

列1～3をコピーしてVBEにペーストすればコードができてる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/f9e73082-d68d-3412-5343-f41e5fb060d3.png)

``` vb:列1
="    With myLV.ListItems.Add: .Text = "&""""&[@key1]&""""
```

``` vb:列2
=": .SubItems(1) ="&""""&[@key2]&""""
```

``` vb:列3
=": .SubItems(2) ="&""""&[@function]&""""&": End With"
```