駅すぱあと VBA SDKを使って、交通費精算時に定期情報の更新を行う

**本記事はヴァル研究所の支援として作成された記事です**

[駅すぱあとはAPIを公開](https://api-info.ekispert.com/)しており、駅情報や経路探索などをAPI経由で行えます。メソッドはすべてGETメソッドで、情報取得系のみです。レスポンスはJSONまたはXMLで返ってきます。

この駅すぱあと APIを利用しやすくするSDKを開発しはじめました。SDKはVBAで作っており、Excelなどから利用できます（Windowsのみ、macOSでは利用できません）。

今回は、交通費精算時に定期情報の更新を行うやり方について、[定期情報の更新 \- 駅すぱあと API Documents 駅データ・経路検索のWebAPI](https://docs.ekispert.com/v1/tips/update-teiki/)に記載されている内容を参考にしたSDKを使って紹介します。


外出時の交通費を申請する場合、通勤定期券を持っている区間は申請から控除しますが、登録していた定期情報で定期控除ができなくなっていた場合に、申請の時に通知が出せると便利です。
定期区間の情報は、駅や路線の新設や廃止があるため、定期情報の定期的な更新を推奨しています。

## 必要な情報

SDKを利用する際にはAPIキーが必要です。[無料トライアルがあるので、こちらから取得](https://api-info.ekispert.com/form/trial/)してください。

## 注意点

- SDKはWindowsでのみ動作します
- SDKは非公式です。公式サポートへの問い合わせはご遠慮ください

## ファイルのインポート

[こちらのリポジトリ](https://github.com/EkispertAPIMania/VBA-SDK)にある `*.cls` と `*.bas` ファイルをすべてインポートします。これらは以下のライブラリを含んでいます。

- [VBA-tools/VBA-Dictionary](https://github.com/VBA-tools/VBA-Dictionary)
- [VBA-tools/VBA-Web: VBA-Web](https://github.com/VBA-tools/VBA-Web)
- [VBA-tools/VBA-JSON](https://github.com/VBA-tools/VBA-JSON)

## 初期化

先ほど取得したAPIキーを使ってSDKを初期化します。

```vb
Dim client As Ekispert
Set client = New Ekispert
client.ApiKey = "YOUR_API_KEY"
```
## 定期券情報の作成

### 定期情報を、定期経路シリアライズデータとして作成する

定期券の情報を作成します。（ここでは、定期券情報がエラーとなるように、あえて廃駅を含む定期経路でサンプルを作成しています。）

```
GET /v1/json/search/course/extreme?key=アクセスキーを入力してください&viaList=長万部:中ノ沢&date=20240301&searchType=plain
```

SDKでは以下のようになります。

```vb
Dim Query As CourseExtremeQuery
Set Query = Client.CourseExtremeQuery()

Query.ViaList(0) = "長万部"
Query.ViaList(1) = "中ノ沢"
Query.DateProp = DateSerial(2024, 3, 1)
Query.SearchType = SearchTypeEnum.Plain

Dim Result As ResultSet
Result = Query.Find()

If Not Result.Success Then
    MsgBox Result.Error.Message
    Exit Sub
End If

Debug.Print Result.Courses(0).Teiki.SerializeData ' シリアライズデータ
Debug.Print Result.Courses(0).Teiki.DisplayRoute ' 表示用文字列
```

定期経路シリアライズデータは `VkV4QaECp8rIAQEDpgE0160EksEBpU55wQGlT5kFkcMBAQMBBKVPmQeRxQGlTnkCpU|ZAwAEAAUACAEKAQwA--7fc83b8180c61894bbec3b4a6b9cadf92b7a9b14--0--63` のようになり、表示用文字列は `長万部--ＪＲ函館本線(函館－長万部)--中ノ沢` のようになります。
## 定期情報の更新

### 定期情報の更新が必要かチェックする

日々の交通費精算の時に、定期区間の控除が失敗していないかをチェックする方法です。APIとしては、以下のように呼び出します（SDKではJSONを使っているので、その部分を変更しています）。

```
GET /v1/json/search/course/extreme?key=アクセスキーを入力してください&viaList=国縫:長万部
&searchType=plain
&assignTeikiSerializeData=VkV4QaECp8rIAQEDpgE0160EksEBpU55wQGlT5kFkcMBAQMBBKVPmQeRxQGlTnkCpU|ZAwAEAAUACAEKAQwA--7fc83b8180c61894bbec3b4a6b9cadf92b7a9b14--0--63
&addAssignStatus=true&checkEngineVersion=false

```

SDKでは以下のようになります。

```vb
Dim Query1 As CourseExtremeQuery
Set Query1 = Client.CourseExtremeQuery()

Query1.AddAssignStatus = True
Query1.ViaList(0) = "浅草"
Query1.ViaList(1) = "とうきょうスカイツリー"
' Query1.ViaList(0) = "浅草:とうきょうスカイツリー" でもOK

Query1.AssignDetailRoute(0) = "浅草"
Query1.AssignDetailRoute(1) = "東武伊勢崎線区間準急"
Query1.AssignDetailRoute(2) = "Down"
Query1.AssignDetailRoute(3) = "業平橋"
' Query1.AssignDetailRoute(0) = "浅草:東武伊勢崎線区間準急:Down:業平橋" でもOK

Dim today As Date
today = Date
Query1.DateProp = today + TimeValue("10:00:00")
```

そして、探索を行います。

```vb
Dim Result1 As ResultSet
Result1 = Query1.Find()

If Not Result1.Success Then
    MsgBox Result1.Error.Message
    Exit Sub
End If

Debug.Print Result1.Courses(0).AssignStatus.RequireUpdate ' 0 
Debug.Print Result1.Courses(0).AssignStatus.Code ' 99
```


`Code` は、指定した定期区間が正しく控除されたかを確認するステータスです。
`Code` が `0` 以外であれば、定期区間の控除ができなかったと判断できます。定期区間の控除ができなかった場合、ステータスコードを確認することで、控除ができない理由を知ることができます。以下は[経路探索 \- 駅すぱあと API Documents 駅データ・経路検索のWebAPI](https://docs.ekispert.com/v1/dictionary/teiki-assign-status/)による `RequireUpdate` の説明です。

```
定期割り当てステータスコード
定期割り当てステータスコードが0以外の場合は、定期区間の運賃は控除されていません。
- 0: 正常に定期経路が割り当てられた。
- 1: 定期券を利用しても運賃が変わらない、または高くなってしまう。
- 2: 定期区間を含む経路ではない。
- 3: 割引乗車券が含まれる経路のため、定期区間の控除計算ができない。
- 4: 定期情報から定期経路を再現できない。
- 99: 予期しない理由により定期経路が割り当てられない。
```

また`RequireUpdate` は、定期券の情報が古くなっていないかを確認するステータスです。
`RequireUpdate` が `0` 以外であれば、定期情報の更新が必要です。以下は[経路探索 \- 駅すぱあと API Documents 駅データ・経路検索のWebAPI](https://docs.ekispert.com/v1/dictionary/teiki-require-update/)による `RequireUpdate` の説明です。

```
定期情報の更新判定ステータスコード
0以外の場合は定期情報の更新が必要です。
- 0: 更新の必要なし
- 1: 定期経路文字列に旧名称の駅名が指定されている
- 2: 定期経路文字列に指定された駅名が見つからない
- 3: 定期経路文字列に旧名称の路線名が指定されている
- 4: 定期経路文字列に指定された路線名が見つからない
- 5: 定期経路文字列の駅名もしくは路線名の廃止など
- 6: 定期経路シリアライズデータが不正
```


### 定期情報を更新する

「定期経路シリアライズデータ」と「定期経路の表示用文字列」を再取得します。APIは以下のように呼び出します。



```
GET /v1/json/search/course/extreme?key=アクセスキーを入力してください&viaList=高円寺:渋谷&searchType=plain
```

SDKでは以下のようになります。 `Teiki.DisplayRoute` が定期経路の表示用文字列です。

```vb
Dim Query1 As CourseExtremeQuery
Set Query1 = Client.CourseExtremeQuery()

' 使い回す場合には Query1.Reset を使ってリセットしてください

Query1.ViaList(0) = "高円寺"
Query1.ViaList(1) = "渋谷"
Query1.SearchType = Plain

Dim Result3 As ResultSet
Result3 = Query1.Find()

If Not Result3.Success Then
    MsgBox Result3.Error.Message
    Exit Sub
End If

Debug.Print Result3.Courses(0).Teiki.SerializeData ' シリアライズデータ
Debug.Print Result3.Courses(0).Teiki.DisplayRoute ' 表示用文字列
```

たとえば定期経路シリアライズデータは `VkV...-81` のようになり、表示用文字列は `高円寺:ＪＲ中央線快速:Up:新宿:ＪＲ山手線内回り:Down:渋谷` のようになります。



このように、APIを直接コールするのに比べて、SDKを使うことで簡単に定期情報の更新が行えます。

## ソースコード

SDKのコードは以下のリポジトリにて公開しています。ライセンスはMIT Licenseです。

[EkispertAPIMania/VBA-SDK: Excel VBAなどで動作する駅すぱあと VBA SDKです（Windowsのみ）](https://github.com/EkispertAPIMania/VBA-SDK/tree/main)

## まとめ

駅情報やルートは適宜更新されるので、定期情報についても定期的な更新チェックが必要です。駅すぱあとAPIを使えば、そうしたチェックの手間を大幅に軽減できます。経費計算などをシステム自動化する際に、ぜひ駅すぱあと APIを利用してください。本SDKを使えば、Excelなどから簡単に利用できます。

何か不具合があれば、Issueにて連絡いただければ対応します（macOSでは動かないので注意してください）。

[EkispertAPIMania/VBA-SDK: Excel VBAなどで動作する駅すぱあと VBA SDKです（Windowsのみ）](https://github.com/EkispertAPIMania/VBA-SDK)