LoginSignup
0
0

More than 1 year has passed since last update.

Autodesk Inventor API Hacking (Rubberduckを使いたい)

Posted at

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を登録しようとしたら一律スキップするようにしました。

TypeAnnotationPass.cs
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\ApplicationAutoCADApp.csなど、アプリケーションごとのfileがあったので、見よう見まねでInventor用を作成しました。

InventorApp.cs
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を修正しました。修正内容は割愛します。
この登録に何の作用があるのか分からないですが、AutoCADSolidWorksも登録しているので、同じようにしておきました。

99. 親の記事に戻る

Autodesk Inventor API Hacking (概略)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0