VSコマンドの一覧表を作成する
VSコマンドの諸元は、VS 2005ではEnvDTE80.DTE2のメンバであるEnvDTE.Commandsコレクションの中のCommandオブジェクトから取得できます。
EnvDTE80はEnvDTEを代替するものではなく、あくまでも変更や拡張を実装するライブラリであるため、EnvDTE80で提供されるオブジェクトメンバの一部がEnvDTEから提供されるなど、あまりすっきりしない構成になっています。
そのため、例えば今回取り上げている
Commandコレクションは、Dim a As EnvDTE80.DTE2.Commands
Dim a As EnvDTE80.DTE2 Dim b As EnvDTE.Commands = a.Commands
今回参照するCommandオブジェクトの主なメンバは次のとおりです。
| メンバ名 | 説明 |
Guid | 今回はこのGuidと下のIDの2つを組み合わせて、すべてのCommandの重複しないキーとして使用します。 |
ID | |
Name | Command名。すべての言語版のVSで共通です。MSDN Library内の記述やTemporary Macroで収集されるVSコマンドは、このメンバの値に基づいています。 |
LocalizedName | 言語ローカルのCommand名。どの言語版かによって値が異なります。英語版ではNameとLocalizedNameは同じ値を持ちます。VS IDEの[オプション]ダイアログ-[環境]-[キーボード]ページに表示されるコマンド名は、このメンバの値に基づいています。 |
CommandsコレクションをFor Eachで回して、各Commandの諸元をテキストファイルに出力することで、簡単にVSコマンドの一覧表が出来上がります。
ソートや検索しやすいようにしておくと後々使い勝手がいいので、ここではExcelで読み込めるCSVファイル(カンマ区切り、文字列はダブルクォーテーションくくり、Shift-JIS)として出力するようにしました。
'*** VSコマンド一覧表の出力(1) ************* ' [Guid、ID、Name、Localname → CSV] で出力 '******************************************* Public Sub GetCommandList1() '*** 文字定数(文字列を短くするため) Const QT As String = CStr(ControlChars.Quote) '*** CSVファイル出力用ストリームライタ Dim CsvW As IO.StreamWriter '*** VSコマンドのCSV出力 Try CsvW = New IO.StreamWriter("C:\VSCommandList1.csv", False _ , System.Text.Encoding.GetEncoding("shift-jis")) For Each cmd As Command In DTE.Commands 'VSコマンド(1つ)→CSV出力(1行) Dim strBf As String = QT & cmd.Guid & QT _ & "," & CStr(cmd.ID) _ & "," & QT & cmd.Name & QT _ & "," & QT & cmd.LocalizedName & QT CsvW.WriteLine(strBf) Next Finally CsvW.Close() End Try End Sub
Commandsコレクションはインスタンスを宣言していません。VS .NET 2003までのEnvDTEライブラリとの互換性から、あらかじめインスタンス変数DTEが用意されていますので、それをそのまま使用しています。
同様に、VS .NET 2003でも動作するよう、VB 2005からの拡張構文Usingではなく従来の例外処理構文Tryを使用しています。
では、実行してみましょう。マクロIDEの中からVSマクロを実行させるには、実行させたいプロシージャの中にカーソルを置いて、メニューから[デバッグ]-[開始]を選択します。
VSマクロが実行されている間は、タスクトレイで(VS IDEのマクロエクスプローラから実行した場合はVS IDEのステータスバー右隅で)小さなカセットテープのアイコンがくるくると回ります。カセットテープアイコンが消えたら、マクロの実行は終了です。
VSコマンド一覧表の使い方
出力した「VSCommandList1.csv」をExcelで読み込むと、次のようになります(見やすいように列幅を整え、xls形式で保存し直してあります)。
せっかくですので、この一覧表の簡単な活用方法もご紹介しましょう。
例えば、ブックマークです。設定してあるブックマークを解除したくはないが、一時的に無効にして動作確認したいといったことがよくあります。
これはVS IDEのメニューから[編集]-[ブックマーク]-[すべてのブックマークを無効にします](ひとつでも無効になっている場合は[すべてのブックマークを有効にします])を使ってトグルでON/OFFできますが、この機能にショートカットキーを割り当てるともっと便利になりそうです。
しかしVS IDEはデフォルトの状態でも2,800以上のVSコマンドを持っており、[オプション]ダイアログの4行ほどしか表示高のないコマンドリストボックスから、ショートカットキーを探し出すのはかなり大変です。
そこで、一度[Temporary Macroの記録]機能を使って[すべてのブックマークを無効にします]を記録し、Temporary Macroが作成したコードを調べてみます。
Sub TemporaryMacro() DTE.ExecuteCommand("Edit.EnableAllBookmarks") End Sub
[すべてのブックマークを無効にします]機能は、「Edit.EnableAllBookmarks」という名前のVSコマンドだということが分かりました。
英名が分かったら、前項で作成したVSコマンド一覧表から「Edit.EnableAllBookmarks」を検索し、対となる日本語名が「編集.すべてのブックマークを有効にします」であることを調べます。ここまで分かれば、後はその日本語名をカット&ペーストで、[オプション]ダイアログの[以下の文字列を含むコマンドを表示]テキストボックスに入力して、目指すVSコマンドをピンポイントで抽出できるようになります。
実際には、VS IDEのメニュー項目は、ほぼVSコマンドのLocalizedNameと等しいので、半角、全角やスペースの有無に気をつけながら[以下の文字列を含むコマンドを表示]テキストボックスにそれらしい文字列を入力するとけっこうヒットするんですが、使い方の例ということでご容赦ください。
本当に重宝するのは、Nameのみで紹介されている英語圏の文献などから得た情報を元に、VSコマンドのショートカットキー割り当てを調べたい時などです。
VSコマンドとショートカットキーの一覧表を作成する
VSコマンドの一覧表が作成できるなら、現在の自分の環境に設定されているショートカットキーの一覧も欲しくなってきます。こちらも[オプション]ダイアログからでは、ひとつひとつVSコマンドにフォーカスを当てながら確認しなければならず、管理が大変面倒です。
Commandオブジェクトには、現在のショートカットキー割り当てを取得できるメンバも用意されています。
| メンバ名 | 説明 |
Bindings | ショートカットキー割り当て(キーバインディング)。複数のショートカットキーを割り当てることができるよう、SafeArrayとなっています |
Bindingsも出力するように修正したVSマクロソースは次のとおりです。
'*** VSコマンド一覧表の出力(2) *********************** ' [Guid、ID、Name、Localname、Bindings → CSV] で出力 '***************************************************** Public Sub GetCommandList2() '*** 文字定数(記述コードを短くするため) Const QT As String = CStr(ControlChars.Quote) '*** CSVファイル出力用ストリームライタ Dim CsvW As IO.StreamWriter '*** VSコマンドのCSV出力 Try CsvW = New IO.StreamWriter("C:\VSCommandList2.csv", False _ , System.Text.Encoding.GetEncoding("shift-jis")) For Each cmd As Command In DTE.Commands 'NameまたはLocalizedNameが空でなければ出力対象 If cmd.Name <> "" AndAlso cmd.LocalizedName <> "" Then 'VSコマンド(1つ)の諸元取得 Dim strBf As String = QT & cmd.Guid & QT _ & "," & CStr(cmd.ID) _ & "," & QT & cmd.Name & QT _ & "," & QT & cmd.LocalizedName & QT If Not cmd.Bindings Is Nothing _ AndAlso cmd.Bindings.GetLength(0) > 0 Then For i As Integer = 0 To cmd.Bindings.GetLength(0) - 1 'ショートカットキー(1つ)→CSV出力 CsvW.WriteLine(strBf & "," & QT & cmd.Bindings(i) & QT) Next Else CsvW.WriteLine(String.Concat(strBf)) End If End If Next Finally CsvW.Close() End Try End Sub
Bindingsは単純に、GetLength(0)で取得した要素数の分だけForループで回しています。
NameまたはLocalizedNameが空文字列のものは内部的に使用されるコマンドだと思われますので、本マクロでは出力しないようにしました。興味のある方は、GetCommandList1()の出力結果と見比べてみてください。


![ショートカットキーを探すのが大変な[オプション]ダイアログ ショートカットキーを探すのが大変な[オプション]ダイアログ](http://cz-cdn.shoeisha.jp/static/images/article/401/CreateVSCommandList11_s.gif)
![ショートカットキーを絞り込んだ[オプション]ダイアログ ショートカットキーを絞り込んだ[オプション]ダイアログ](http://cz-cdn.shoeisha.jp/static/images/article/401/CreateVSCommandList12_s.gif)