VSCode(twinBASIC拡張)でVBScriptをデバッグする

# はじめに
これは、[Visual Basic Advent Calendar 2022](https://qiita.com/advent-calendar/2022/vb)の4日目の記事となります。

VBScriptのプログラムを作る時にはデバッグができないので、MsgBoxで値を出したりして確認していました。
かといってVSCodeにはVB用の拡張機能があっても、シンタックスハイライトするくらいです。それではとVBScriptでデバッグが出来る方法を模索しました。

模索中に別件ですがVSCodeでVBA開発する拡張機能があることを知りました。ただしデバッグは出来ません。

https://note.com/shikao29/n/n2eb03cbf92fa

【2023/01/15追記】
twinBASICの新版は専用の統合IDEを使用しています。これでもVBScriptのデバッグは可能です。

https://qiita.com/yaju/items/3729c00b236bb8f2ba53

# VBScriptのデバッグ
## VbsEditを使う
遅ればせながら「[VbsEdit](https://www.vbsedit.com/)」を知りました。有償 5,900円ではありますが、デバッグも可能です。
トライアル版では、デバッグ機能を使う際に3秒間ほど待ち時間が発生するそうです。

https://step-learn.com/article/vbscript/119-vbsedit.html

## VBE(Visual Basic Editor)を使う
ExcelのVBEを使用すれば、多少の違いはありますがデバッグは出来ますね。

https://qiita.com/saeki4n/items/fc1e19c8b2348230d6b6

## VSCodeでtwinBASIC拡張を使う
今回、紹介する方法になります。
[twinBASIC](https://twinbasic.com/)は、Visual Basic 6.0の100％互換ソフトで[CWaynePhillipsEA](https://twitter.com/WaynePhillipsEA)さんが個人で開発しています。最新版はVSCodeのソースをもとにウェブブラウザー上で動くようした[Monaco Editor](https://microsoft.github.io/monaco-editor/index.html)で開発されているものの、初期開発版はVSCodeの拡張機能として作成されており、デバッグすることも可能です。

# twinBASICによるデバッグ方法
## インストール方法
先ずはVSCodeでtwinBASICをインストールしてください。

https://qiita.com/yaju/items/6ed4a4c3fcd7b0c24cab#%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB

プロジェクトは、HelloworldProjectのままでいいです。

### 警告メッセージ
下記の警告メッセージがでますが「NO」を選択してください。最新版はMonaco EditorによるIDEで開発されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/fb91c1ce-a7eb-3da2-6ba5-02cf3bd3a684.png)
>INFO:このtwinBASIC VSコードエクステンションの開発は2023年まで一時停止されます。
この拡張機能は引き続き使用できますが、現在、より最新で多くの新機能とバグフィックスを含む専用のIDEをデベロップしていることに注意してください。
新しいtwinBASIC IDEについてもっと知りたいですか？

## VB6.0とVBSの差を吸収する
twinBASICは、VB6.0の100％互換ソフトなので、VBEとは言語仕様的に同じですがVBSと違いがあります。

* VBSでは変数の型指定ができない
* [VBA の機能で VBScript に含まれていない機能](https://learn.microsoft.com/ja-jp/previous-versions/windows/scripting/cc392401(v=msdn.10))

## WScript機能をVBAでエミュレートとする
WScriptをエミュレートするWScriptObjを作成します。
全部作る必要はなく必要になった機能を実装していくのがいいでしょう。

```vb
Class WScriptObj

    Public Function Echo(ByVal message)
        MsgBox message
    End Function

    Public Sub Sleep(ByVal time)
        Dim tempDate As Date
        time = time / 1000
        tempDate = DateAdd("s", time, Now)
        Do
            DoEvents
        Loop While Now < tempDate
    End Sub

    Public Sub Quit()
        End
    End Sub

End Class
```

## twinBASICでのVBSの開発例
サンプルソースは下記サイトを元にしています。
[VBScriptをお手軽にデバッグして開発する方法](https://qiita.com/saeki4n/items/fc1e19c8b2348230d6b6)
VBAではないのでScriptFullNameやScriptNameは除外しています。
その代わり、Echoを追加しました。

```vb
Class WScriptObj

    Public Function Echo(ByVal message)
        MsgBox message
    End Function

    Public Sub Sleep(ByVal time)
        Dim tempDate As Date
        time = time / 1000
        tempDate = DateAdd("s", time, Now)
        Do
            DoEvents
        Loop While Now < tempDate
    End Sub

    Public Sub Quit()
        End
    End Sub

End Class

Module ModHelloWorld
    ' This project type is set to 'Standard EXE' in the Settings file, so you need a Main() subroutine to run when the EXE is started.
    Public Sub Main()

        Dim a
        Dim b
        Dim c
        a = 1
        b = 2
        c = a + b
        WScript.Echo c

        Dim WScript As New WScriptObj
        'VBS特有の機能をVBAで使用する
        Dim RetStr, regEx, Match, Matches   ' 変数を作成します。
        Set regEx = CreateObject("VBScript.RegExp")   ' 正規表現を作成します。
        regEx.Pattern = "aiu"   ' パターンを設定します。
        regEx.IgnoreCase = True   ' 大文字と小文字を区別しないように設定します。
        regEx.Global = True   ' 文字列全体を検索するように設定します。
        Set Matches = regEx.Execute("123aiueo")   ' 検索を実行します。
        For Each Match In Matches   ' Matches コレクションに対して繰り返し処理を行います。
           RetStr = RetStr & "一致する文字列が見つかった位置は、"
           RetStr = RetStr & Match.FirstIndex & " です。一致した文字列は、"
           RetStr = RetStr & Match.Value & " です。" & vbCrLf
        Next
        MsgBox RetStr               '正規表現結果を出力する
        WScript.Sleep 3000          ' 3秒待機
        WScript.Echo "テスト"
        WScript.Quit                ' 終了する
        MsgBox "ここは実行されない"

    End Sub

End Module
```

例として、`WScript.Echo c`の部分でブレークポイントを置きます。
Public Sub Mainの上にある「▶ run ModHelloWorld.Main」をクリックするとデバッグが開始されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/a3ac1680-0cf0-7899-ffae-1e87b064579c.png)

ブレークポイントで止まるので、ウォッチの値などを見てデバッグすることが出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/45f8d4e9-000e-1103-1722-ec0b13b18128.png)

# 最後に
この方法で、VSCodeを使用してVBScriptをデバッグすることが出来ました。
あくまでロジックの確認として使用するのに限定されますが、何も無いよりは便利だと思います。
VBScriptに拘らないなら、twinBASICとしてビルドしてしまえば、exeが作成出来ますよ。