0. はじめに
Freeradicalの中の人、yamarahです。
Rubberduck良いですよね。VBAで作業するなら是非とも使いたいツールですが、InventorのVBAではうまく動作しません。
今回はいつもと趣向を変えて、RubberduckをInventorに対応させる方法について検討します。
1. そのままbuildする
まずは本家のgithubからソースを入手します。
buildには、VisualStudio2019が必要でした。私の能力では、2022ではエラーを解消しきれませんでした。
また、RubberduckTests\Inspections\ConstantNotUsedInspectionTests.cs
が文字エンコードの問題でerrorになったので、UTF-8で保存しなおす必要がありました。しかし、本当にUTF-8で保存しなおして良いのかは疑わしいです。テストのcodeのようなので、深追いせずこれで良しとします。
これらの問題は、日本語の開発環境が原因のように思われます。万全を期すなら、英語環境を構築してbuildすると良いと思います。
buildが成功すると、Installerが作られるのではなくWindowsのレジストリに登録されます。つまりはinstall後の状態になるようです。ですので、配布バイナリーをinstall済みでしたら、build前にuninstallしておくことをお勧めします。
2. Errorを追いかける
ちなみに、2019年ごろに試したときは、InventorのVBAには全く反応しなかったのですが、現在のバージョン(2.5.2.5906)だと配布バイナリーでも、とりあえずはInventorのVBAを認識ます。
しかし、Rubberduckの解析をリフレッシュすると、Resolver ErrorとなりRefactorを始めとする多くの機能が動作しません。
Errorの原因を確認する
debuggerで追いかけると、RubberduckがInventorのAPIを舐めて内部辞書を作成する際に、Circle
という名のclass(C#的にはstruct?)に遭遇すると例外送出 → Resolver Errorとなっていました。
構文解析のlibraryから例外送出されているので、直接の原因までたどり着けませんでしたが、Inventorがどうこうではなく、Circle
という単語に反応しているようです。
試しに、vanillaのVBAで以下のcodeを試してみます。
Sub test()
dim Circle as Object
End Sub
このcodeが既にVBAで構文エラー扱いになります。どうやら、Circle
が何か特別扱いを受けているようです。
Circle
の扱い
そんな馬鹿な、という感じですが、ググって次の記事を発見しました。
undocumented vba special keywords - Circle and Scale
どうも起源はQuick Basicにまで遡るようで、その頃のkeywordが現代にまで受け継がれているのが原因のようです。Line
などは、なぜO.K.になったのでしょうか・・・
3. 対策
先に書いた通り、Rubberduckが参照している全てのdllの名前を舐めて内部辞書を作るようなので、その際にColor
を登録しようとしたら一律スキップするようにしました。
public void Execute(IReadOnlyCollection<QualifiedModuleName> modules)
{
var toDetermineAsTypeDeclaration = _declarationFinder
.FindDeclarationsWithNonBaseAsType()
.Where(decl => decl.AsTypeDeclaration == null
|| modules.Contains(decl.QualifiedName.QualifiedModuleName));
foreach (var declaration in toDetermineAsTypeDeclaration)
{
+ if (declaration.CustomFolder == "Inventor" &&
+ declaration.AsTypeName == "Circle")
+ {
+ continue;
+ }
AnnotateType(declaration);
}
}
対処療法なので、本当にスキップして良いのか、副作用が無いのか分からないですが、今のところは問題なく動作しています。
4. ついでに
Rubberduck.VBEditor.VBA\SafeComWrappers\Application
にAutoCADApp.cs
など、アプリケーションごとのfileがあったので、見よう見まねでInventor用を作成しました。
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
// ReSharper disable once CheckNamespace - Special dispensation due to conflicting file vs namespace priorities
namespace Rubberduck.VBEditor.SafeComWrappers.VBA
{
public class InventorApp : HostApplicationBase<Inventor.Application>
{
public InventorApp(IVBE vbe) : base(vbe, "Inventor", true) { }
}
}
また、これを参照すべく、Rubberduck.VBEditor.VBA\SafeComWrappers\VB\VBE.cs
を修正しました。修正内容は割愛します。
この登録に何の作用があるのか分からないですが、AutoCAD
やSolidWorks
も登録しているので、同じようにしておきました。