Open kazurayam opened 3 months ago
下記の記事がたぶん元ネタ
https://www.codeproject.com/articles/640258/deconstruction-of-a-vba-code-module
この中にこんな記述がある。
|UniqueNames | | Count of unique procedure names from all modules|
うーん、ここに何かありそうな気がする。
サンプルコードをダウンロードして中を見てみよう。もちろんExcelが要る、Windowsでね。
読んでみた。
VBAソースコードを構文解析した結果として外部のモジュールのプロシジャを参照してます、という関係性が参照可能になっていレバいいいなあと期待していた。
ざんねんながらなかった。VBAのソースコードはソースコードのまま放置されている。
だめだ。
もう一度みよ
VBソースを解析するコードを自作するなんていう仕事はやりたくない
VBコンパイラに働きかけて構造化データを取り出すことはできないだろうか?
このアイディアの優先順位は高い。最重要課題だ。しかし実現が困難であることもわかっている。
https://qiita.com/mochimo/items/e9be36619a76e15bc898 によれば Rubberduck が
プロシジャや変数のすべての参照の検索
という機能を実現していると。
これですよ、これ。VBCallGraphが必要としているのは。
RubberduckをAPI経由で呼び出せるんだろうか?
Rubberduckが素晴らしい能力の持ち主であることがわかった。実例をあげて説明しよう。「会費納入状況チェック」のxlsmを開きVBEを開いた。
ツールバーにRubberduckのメニューがある。それをクリックするとドロップダウンメニューが開く。
ここに
Code Inspections
というメニューあることに注目しよう。これをマウスでクリックするとCode Inspectionsとラベルがついたウインドウが開く。
このウインドウを初めて開いたとき Rubberduck doesn’t see anything yet. というメッセージが表示される。なにかきっかけを与えればRubberduckはなにか凄いことを見つけるこができるだろうと期待できそう。そこでこのウインドウの左上隅にある青い矢印がふたつ巴になっているアイコンをクリックしてみた。
青いアヒルが輪になって踊っているのを数秒眺めていたら、こうなった。
どうやらRubberduckはVBAソースコードをコンパイルしてAbstract Syntax Treeを構築しそれを解析して、VBAコード群にたいして様々のことを知ったようだ。
この段階であらためてVBEのツールバーに戻ろう。Rubberduckのメニューをひらくと Navigate というサブメニューがあるのに気付いた。Navigateメニューを開くとそこに Find All References というメニューがあった。
会費納入状況チェック.xlsmはBackbone.xlamを参照している。BackboneのKzWorksheetモジュールのソースコードをエディタで開きKzIsWorksheetPresentInWorkbook関数にマウスカーソルを置いてみた。するとSearch Resultというウインドウが開いて下記のような表示になった。
Search Resultウインドウには、BackboneのKzWorksheetモジュールのKzIsWorksheetPresentInWorkbook関数が どこで参照されているかを列挙して表示している。たとえば上記のスクリーンショットをみると、
MemberプロジェクトのAoMemberUtilsモジュールのFetchMemberTable関数がそれを参照している。20行目の25カラム目から55カラム目に KzIsWorksheetPresentInWorkbook という文字が書いてある
という情報が表示されている。
すごいなあ、Rubberduck。Search All ReferencesのSearch Resultの情報こそ、VBACallGraphが求めている情報だ。とくに素晴らしいのがReferrerが プロジェクト名.モジュール名.プロシジャ名 によって識別されていることだ。下記のスクリーンショットをみよ。
Referrerのモジュール名が「会費納入状況チェック」、プロシジャ名が「Main」であること、そしてMainがFunctionではなくてStandard Procedureであることが把握され、表示されている。kazurayamのVBACallGraphはこのレベルの情報が把握できていない。
というよりも、RubberduckのSearch All Referencesがあるならば、VBACallGraphなるJavaプログラムがそもそも要らないんじゃないのか?
VBACallGraph無用論をとりあえず封印しよう。あとで考えよう。
RubberduckのSearch All ReferencesのSearch Resultの情報をわたしはワークシートに文字情報として取り出したい。どうすればできるか?RubberduckがAPIを公開してくれていればいいのだが。そのAPIをCallしさえすればSearchResultが文字として取り出せる、んだといいなあ。
ワークシートに文字情報として保存できたら、VBACallGraphに渡せるから。
Find all References に関する説明がある
https://rubberduckvba.com/Features/Summary?name=FindReferences
「会費納入状況チェック」.xlsmを開いた。VBEを開いた。「ツール(T)」をクリックして「参照設定」ダイアログを呼び出した。参照可能なAddinが列挙された。そのなかを探したら
Rubberduck Addin
があった。
ってことは、RubberduckのUIでFind All Referencesという名前で呼ばれている機能がAddIn化されているのだ。だからVBAコードをわたしが自作してRubberduc Addinをcallするができる。ぜんぶのReferenceにかんする情報をひとつのワークシートに出力して保存することがたぶんできる。そのFind All ReferencesのResultをVBACallGraphが読めばいい。
Rubberduck Addinを使いこなすには、kazurayamはVBAプログラミングの実力が足りない。基礎からちゃんと学習する必要がある。 つぎにするべきことはわかった。 いったんこのissueを閉じよう。
Rubberduck Addinをオブジェクトブラウザーで開いて中身を眺めた。
Unit Testを実現するためにつかうRubberduckのモジュールが見えた。 しかしFind All Referencesにかんするモジュールはみあたらなかった。
Rubberduckの開発者はFile All Referencesに関するモジュールをユーザが自作のVBAlコードから参照可能にはしなかったようだ。惜しい。じつに惜しい。なんとかできないか?
7 を参照。「プロシジャ一覧を作る」モジュール
このコードによって、VBAモジュールが(ソースコードではなく)解析された後の構造体としてアクセス可能になる。この構造体の中からデータを抽出して「プロシジャ一覧」シートを作っている。
ひょっとして、VBAプロシジャが他のどのプロしじゃをCallしているかという情報がCodeModuleの中に含まれていないだろうか?もしそうならば #15 #17 を解決することができるだろうj。