kazurayam / vba-callgraph

Generating a Call Graph for Excel VBA workbooks
https://kazurayam.github.io/VBACallGraph/
Apache License 2.0
0 stars 0 forks source link

Referrerであるプロシジャ(SubまたはFunction)がどのプロシジャ(Sub or Function)を参照しているかの情報をVBAのAPIを利用して取り出したい #25

Open kazurayam opened 3 months ago

kazurayam commented 3 months ago

7 を参照。「プロシジャ一覧を作る」モジュール

Set VVC = wb.VBProject.VBComponents(sMod).CodeModule

このコードによって、VBAモジュールが(ソースコードではなく)解析された後の構造体としてアクセス可能になる。この構造体の中からデータを抽出して「プロシジャ一覧」シートを作っている。

ひょっとして、VBAプロシジャが他のどのプロしじゃをCallしているかという情報がCodeModuleの中に含まれていないだろうか?もしそうならば #15 #17 を解決することができるだろうj。

kazurayam commented 3 months ago

下記の記事がたぶん元ネタ

https://www.codeproject.com/articles/640258/deconstruction-of-a-vba-code-module

この中にこんな記述がある。

image

|UniqueNames |   | Count of unique procedure names from all modules|

うーん、ここに何かありそうな気がする。

サンプルコードをダウンロードして中を見てみよう。もちろんExcelが要る、Windowsでね。

kazurayam commented 2 months ago

MProject_v2.zip

MProject.bas.txt

読んでみた。

VBAソースコードを構文解析した結果として外部のモジュールのプロシジャを参照してます、という関係性が参照可能になっていレバいいいなあと期待していた。

ざんねんながらなかった。VBAのソースコードはソースコードのまま放置されている。

kazurayam commented 2 months ago

だめだ。

kazurayam commented 2 months ago

もう一度みよ

VBソースを解析するコードを自作するなんていう仕事はやりたくない

kazurayam commented 2 months ago

VBコンパイラに働きかけて構造化データを取り出すことはできないだろうか?

kazurayam commented 2 months ago

このアイディアの優先順位は高い。最重要課題だ。しかし実現が困難であることもわかっている。

kazurayam commented 2 months ago

https://qiita.com/mochimo/items/e9be36619a76e15bc898 によれば Rubberduck が

プロシジャや変数のすべての参照の検索

という機能を実現していると。

image

これですよ、これ。VBCallGraphが必要としているのは。

RubberduckをAPI経由で呼び出せるんだろうか?

kazurayam commented 2 months ago

https://github.com/rubberduck-vba/Rubberduck/wiki/Viewing-a-live-preview-of-parse-tree

parse tree visualized

なんだか凄いのがいた。

kazurayam commented 2 months ago

Rubberduckが素晴らしい能力の持ち主であることがわかった。実例をあげて説明しよう。「会費納入状況チェック」のxlsmを開きVBEを開いた。

image

ツールバーにRubberduckのメニューがある。それをクリックするとドロップダウンメニューが開く。

image ここに

Code Inspections

というメニューあることに注目しよう。これをマウスでクリックするとCode Inspectionsとラベルがついたウインドウが開く。

image

このウインドウを初めて開いたとき Rubberduck doesn’t see anything yet. というメッセージが表示される。なにかきっかけを与えればRubberduckはなにか凄いことを見つけるこができるだろうと期待できそう。そこでこのウインドウの左上隅にある青い矢印がふたつ巴になっているアイコンをクリックしてみた。

image

青いアヒルが輪になって踊っているのを数秒眺めていたら、こうなった。

image

どうやらRubberduckはVBAソースコードをコンパイルしてAbstract Syntax Treeを構築しそれを解析して、VBAコード群にたいして様々のことを知ったようだ。

この段階であらためてVBEのツールバーに戻ろう。Rubberduckのメニューをひらくと Navigate というサブメニューがあるのに気付いた。Navigateメニューを開くとそこに Find All References というメニューがあった。

image

会費納入状況チェック.xlsmはBackbone.xlamを参照している。BackboneのKzWorksheetモジュールのソースコードをエディタで開きKzIsWorksheetPresentInWorkbook関数にマウスカーソルを置いてみた。するとSearch Resultというウインドウが開いて下記のような表示になった。

image

Search Resultウインドウには、BackboneのKzWorksheetモジュールのKzIsWorksheetPresentInWorkbook関数が どこで参照されているかを列挙して表示している。たとえば上記のスクリーンショットをみると、

MemberプロジェクトのAoMemberUtilsモジュールのFetchMemberTable関数がそれを参照している。20行目の25カラム目から55カラム目に KzIsWorksheetPresentInWorkbook という文字が書いてある

という情報が表示されている。


すごいなあ、Rubberduck。Search All ReferencesのSearch Resultの情報こそ、VBACallGraphが求めている情報だ。とくに素晴らしいのがReferrerが プロジェクト名.モジュール名.プロシジャ名 によって識別されていることだ。下記のスクリーンショットをみよ。

image

Referrerのモジュール名が「会費納入状況チェック」、プロシジャ名が「Main」であること、そしてMainがFunctionではなくてStandard Procedureであることが把握され、表示されている。kazurayamのVBACallGraphはこのレベルの情報が把握できていない。

kazurayam commented 2 months ago

というよりも、RubberduckのSearch All Referencesがあるならば、VBACallGraphなるJavaプログラムがそもそも要らないんじゃないのか?

kazurayam commented 2 months ago

VBACallGraph無用論をとりあえず封印しよう。あとで考えよう。

RubberduckのSearch All ReferencesのSearch Resultの情報をわたしはワークシートに文字情報として取り出したい。どうすればできるか?RubberduckがAPIを公開してくれていればいいのだが。そのAPIをCallしさえすればSearchResultが文字として取り出せる、んだといいなあ。

ワークシートに文字情報として保存できたら、VBACallGraphに渡せるから。

kazurayam commented 2 months ago

Find all References に関する説明がある

https://rubberduckvba.com/Features/Summary?name=FindReferences

kazurayam commented 2 months ago

In https://rubberduckvba.blog/2016/05/04/vba-rubberducking-part-1/

image
kazurayam commented 2 months ago

「会費納入状況チェック」.xlsmを開いた。VBEを開いた。「ツール(T)」をクリックして「参照設定」ダイアログを呼び出した。参照可能なAddinが列挙された。そのなかを探したら

Rubberduck Addin

があった。

image

ってことは、RubberduckのUIでFind All Referencesという名前で呼ばれている機能がAddIn化されているのだ。だからVBAコードをわたしが自作してRubberduc Addinをcallするができる。ぜんぶのReferenceにかんする情報をひとつのワークシートに出力して保存することがたぶんできる。そのFind All ReferencesのResultをVBACallGraphが読めばいい。

kazurayam commented 2 months ago

Rubberduck Addinを使いこなすには、kazurayamはVBAプログラミングの実力が足りない。基礎からちゃんと学習する必要がある。 つぎにするべきことはわかった。 いったんこのissueを閉じよう。

kazurayam commented 2 months ago

Rubberduck Addinをオブジェクトブラウザーで開いて中身を眺めた。

Unit Testを実現するためにつかうRubberduckのモジュールが見えた。 しかしFind All Referencesにかんするモジュールはみあたらなかった。

image

Rubberduckの開発者はFile All Referencesに関するモジュールをユーザが自作のVBAlコードから参照可能にはしなかったようだ。惜しい。じつに惜しい。なんとかできないか?