【Excel VBA】仕様書自動作成ツール作ってみた

# What is this?

**VBAソースコード**を読み込み、特定の記法に従ったコメントをまとめて**Markdown**形式で出力するツール。

## 背景
- 業務自動化をするためExcel VBA/マクロを開発する際に、仕様書どうする問題が常につきまとう
- ケースバイケース・個人の宗教によって下記２つの意見に割れることが多い
    - いくらマクロであれ、仕様書は作成するべき派
    - マクロレベルのツールはエンドユーザーで開発されるべきもので、保守もユーザーですべきだから仕様書はいらない派
- 最小限のコストで仕様書を作成できれば、どちらの論調も解決するのでは？と思い、VBAの仕様書自動作成ツールを作ってみた

## ソースコード
GitHub: https://github.com/daikichidaze/VBASpecDocGenerater

# 構成
## 実行環境
- Python 3.7
    - Anacondaを利用
- Node.js 14.7
    - Windows10環境で開発したため、Node.js環境はscoopを用いて構築
    - パッケージマネージャーはyarnを使用

## モジュール構成
※Pythonでjavascriptモジュールを呼ぶというなんとも格好のつかない構成になっていますが、私自身のNode.js経験がない中、空き時間で開発する必要があったためこのような選択に…。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214822/4e9e1204-4ce5-ebaf-8366-c2d38bde9abd.png)

- main.py
    - メインに動作するプログラム
    - 図内の処理を実行
        - ファイル読み書き
        - それぞれのモジュールへデータを渡す前処理
- VBAソースコード
    - basファイルとclsファイルに対応
    - Excel標準VisualBasicIDEにてエクスポート可能
- XDocGen
    - Javascriptモジュール
        - [GitHub](https://github.com/x-vba/xdocgen)
    - VBAソースコードを読み込み、ソース内のコメント（所定のフォーマット）をJSON形式に変換
    - PyExecJSライブラリを利用して実行
- json2md
    - Javascriptモジュール
        - [GitHub](https://github.com/IonicaBizau/json2md)
    - jsonをmarkdown形式に変換
    - markdown形式としての情報（見出し・箇条書き・表等）を渡す必要があるため、main.py内で指定
    - 上記同様にPyExecJSライブラリから実行
- PyExec
    - pythonから

# 使い方
パッケージをインストールする前に実行環境の整備が必要

## Package Install
### PyExecJS

```bash
pip install PyExecJS
```

### json2md

```bash
yarn install indento
yarn install json2md
```

windows10環境で開発されているため、yarnコマンドは使用するパッケージマネージャに合わせたコマンドをご使用ください

## VBAソースコードへのコメント追加

- 基本的に[XDocGen](https://x-vba.com/xdocgen/)ホームページの記法に準拠
- 具体的な記述方法は次節を参照のこと

### 記法解説

#### 1. Module Level Tags
- 各モジュール（Sub, Function, Property）の外側に記述
- XDocGen自体はどのような単語も対応している
- 本ツールはMarkdownへ変換する都合上、`@Module` と `@Property` のみ対応
    - ツールの仕様上は、ModuleとPropertyどちらをつけるかは自由。
    - `@Module`：Sub, Function, `@Property`: Property とするのが無難
####2. Procedure Level Tags
- 公式HPにある通り、指定のタグのみ対応
- 本ツールでは特に下記タグに対応

|記法|内容|
|----|----|
|`@Description`|関数の詳細記述|
|`@Param`|引数の説明｡各引数名のあとに説明を記述（詳細は次節）|
|`@Return`|返り値の説明|

# サンプルコード
## Input VBA (.basファイル or .clsファイル)

```vb:sample.bas
'@Module: Example module
Public Function ExampleFunction(arg1 As Long, arg2 AS String) As String
	'@Description: This function is a sample function
	'@Param: arg1 First argument
	'@Param: arg2 Second argument
	'@Returns: Returns sample string	
	ExampleFunction = "example"
End Function

'@Property: Example property
Property Get ExampleProperty()
	'@Description: Get example property
	'@Returns: Returns sample string
    ExampleProperty = "example"
End Property
```

## Output Markdown (.mdファイル)

```markdown:sample.md
# example.bas
## Module: ExampleFunction
Example module
### **Basic infomation**

| key | value |
| --- | ----- |
| Name | ExampleFunction
Scope | Public
Static | False
Procedure | Function
Type | String
Description | This function is a sample function
Returns | Returns sample string	 |

### **Parameter**
| index | Name | Optional | Passing | ParamArray | Type | Array | Default | Description |
| ----- | ---- | -------- | ------- | ---------- | ---- | ----- | ------- | ----------- |
| 1 | arg1 | False | ByRef | False | Long | False | None | First argument
2 | arg2 | False | ByRef | False | String | False | None | Second argument |

--- 
## Property: ExampleProperty(Get)
Example property

### **Basic infomation**

| key | value |
| --- | ----- |
| Name | ExampleProperty(Get)
Scope | Public
Static | False
Procedure | Property
Type | Variant
Description | Get example property
Returns | Returns sample string |

---
```

# pythonコードの実行

```bash
python main.py [input folder directory] [output folder directory]
```

- 引数（ `input folder directory`）で設定したディレクトリ内の、すべての ".bas" ファイルと".cls" ファイルが読み込まれる
- 引数（`output folder directory`）で設定したディレクトリへそれぞれの入力ファイル名に対応したmarkdownファイルが出力される

## Ignore file list

- `ignore_file_list.txt` に設定されているファイルはmarkdownファイルを生成しない