はじめに
VBA解析ツールやコード一覧UIを作ると、「このプロシージャをVBEで開く」機能が欲しくなります。
ただし、CodePaneのSetSelectionでプロシージャ全体を範囲選択すると、VBEが選択範囲の末尾を基準にスクロールし、プロシージャ先頭が画面外になることがあります。
この記事では、VBEを前面化し、開始行へカーソルを置き、TopLineで表示位置を固定する実装パターンを紹介します。
使う場面
- VSTOアドインからVBAモジュールを開きたい
- コード一覧のダブルクリックで該当プロシージャへ移動したい
SetSelectionしたのに先頭行が見えない問題を避けたい- VBA解析ツールからVBEへ自然にジャンプさせたい
解決コード
vbe-codepane-jump.cs
csharp
コードを読み込み中...重要なのは、範囲選択ではなくゼロ幅選択にすることです。
pane.SetSelection(startLine, 1, startLine, 1);
そのうえで、pane.TopLine = startLineを指定すると、目的行を画面上部に寄せやすくなります。
呼び出し順序
順序は次のようにします。
- VBE本体を表示する
CodePane.Show()で対象ペインを表示するSetSelection(startLine, 1, startLine, 1)でカーソルを置くTopLine = startLineでスクロール位置を固定する
Show()より前にSetSelectionしても、ウィンドウが未表示の状態ではスクロール位置が期待通りにならないことがあります。
注意点
- VBIDEを扱うため、「VBAプロジェクトオブジェクトモデルへのアクセスを信頼する」が必要です。
- 保護されたVBProjectはスキップします。
TopLineは状態によって例外になる場合があるため、try/catchで囲みます。- 行番号は1始まりです。
- COM越しのプロパティアクセスは例外が出やすいため、個別に安全化すると安定します。
- 開始行の特定は、
ProcStartLineだけに頼らず、自前のLexerやParserで求めるとズレを減らせます。
このテクニックを使っているアプリ
このノウハウは、配布アプリ「階層化フォーム (IKI-Kaiso VSTO版)」で実装・確認しています。
まとめ
VBEジャンプでは、範囲選択でプロシージャ全体を選ぶより、開始行へカーソルを置いてTopLineで表示位置を決める方が安定します。
コード一覧UIやVBA解析ツールからVBEへ飛ばす場合は、Visible、Show、SetSelection、TopLineの順序を固定しておくと、利用者が「どこに飛んだか分からない」状態を避けやすくなります。
