駅すぱあと VBA SDKを使って、定期区間控除を利用した経路探索を行う

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

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

この駅すぱあと APIを利用しやすくするSDKを開発しています。SDKは[VBA](https://github.com/EkispertAPIMania/VBA-SDK)と[Python](https://github.com/EkispertAPIMania/python-sdk)で開発していますが、どちらも非公式SDKなので、公式への問い合わせはご遠慮ください。

今回は、VBA SDKを使って、定期券利用時の運賃計算を行ってみます。特に、定期区間控除がある場合について解説しますので、実際の算出時の参考にしてください。[EkispertAPIMania/VBA\-SDK: Excel VBAなどで動作する駅すぱあと VBA SDKです（Windowsのみ）](https://github.com/EkispertAPIMania/VBA-SDK)の実践的な使い方として、参考にしてください。

## 定期区間控除とは？

定期区間控除とは、定期券を利用している区間の運賃を控除する仕組みです。例えば、A駅からB駅までの定期券を持っている場合、A駅からC駅までの経路探索を行うと、A駅からB駅までの運賃は控除されます。交通費の精算などに使われ、経費精算での二重払いを防ぐために利用されます。

## 利用している機能

このデモでは、SDKの以下の機能を使っています。

- [経路探索](https://docs.ekispert.com/v1/api/search/course/extreme.html?utm_source=qiita&utm_medium=referral&utm_campaign=api-column&utm_id=202505-2)

![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/d5f5b304-c998-40c0-97ea-6837b12dc0fb.png)

## セットアップ

[Releases · EkispertAPIMania/VBA\-SDK](https://github.com/EkispertAPIMania/VBA-SDK/releases)にて公開しているExcelファイルをダウンロードするか、リポジトリをクローンした上で[vbaidiot/ariawase](https://github.com/vbaidiot/ariawase)を使ってコンパイルします。

```bash
git clone https://github.com/vbaidiot/ariawase.git
cd ariawase
mkdir src
```

この `src` の中に[SDKのリポジトリ](https://github.com/EkispertAPIMania/VBA-SDK)をクローンします。名前は `Ekispert.xlsm` です。

```bash
git clone https://github.com/EkispertAPIMania/VBA-SDK.git Ekispert.xlsm
```

そして、`ariawase` ディレクトリに移動して、以下のコマンドを実行します。

```bash
cd ..
cscript vbac.wsf combine
```

そうすると `bin` ディレクトリの中に `Ekispert.xlsm` が生成されます。このファイルの中に、SDKのコードが入っています。

## Excelファイルの作成とSDKのインストール

新しいExcelファイルをマクロの有効なファイルとして作成します（.xlsmファイルになります）。開発メニューを開いて、Visual Basicを選択します。

![image4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/d8a79269-b524-4ecd-9e07-c1dc194cd05c.png)

一緒に、先ほど作成した（またはダウンロードした）SDKのExcelファイルを開きます。標準モジュール、クラスモジュールをすべてコピー（ドラッグ&ドロップ）してください。

![image5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/62647076-6cc2-4625-ab49-170a40aa7170.png)


これで、ExcelファイルにSDKが組み込まれました。

## SDKの初期化

次に、SDKを初期化します。VBAのコードエディタで新しいモジュールを作成し、以下のコードを入力します。

```vb
Dim client As Ekispert
Set client = New Ekispert
client.apiKey = "YOUR_API_KEY"
```

## 定期経路シリアライズデータの作成

まず、定期券を利用している区間に関する経路データを作成します。探索する際には `定期経路文字列` も利用できますが、今回は [定期経路シリアライズデータ](https://docs.google.com/document/d/1G9ZCEdDvtEnAWQK3AkSGZeVjGKFM3pSlZWOUtZqvGG8/edit?tab=t.0#:~:text=https%3A//docs.ekispert.com/v1/dictionary/teiki%2Dserialize%2Ddata/%3Futm_source%3Dqiita%26utm_medium%3Dreferral%26utm_campaign%3Dapi%2Dcolumn%26utm_id%3D202505%2D2) を使っています。

探索には `CourseExtremeQuery` を使います。以下のコードにて、高円寺から池袋までの経路を探索し、定期経路シリアライズデータを取得します。

```vb
Dim Query As CourseExtremeQuery
Set Query = client.CourseExtremeQuery()
Query.ViaList(0) = "高円寺"
Query.ViaList(1) = "池袋"
Query.CheckEngineVersion = False
Dim Result As ResultSet
Result = Query.Find()
If Result.Success = False Then
    Debug.Print Result.Error.Message
End If

Dim SerializeData As String
' 定期経路シリアライズデータを取得
SerializeData = Result.Courses(0).Teiki.SerializeData
```

## 定期経路シリアライズデータを使った経路探索

次に、取得した定期経路シリアライズデータを使って、定期区間控除を利用した経路探索を行います。以下のコードを実行します。

```vb
' 探索条件をリセット
Query.Reset
Query.ViaList(0) = "高円寺"
Query.ViaList(1) = "渋谷"
Query.AssignTeikiSerializeData = strSerializeData ' 取得した定期経路シリアライズデータを設定
Result = Query.Find()
If Result.Success = False Then
    Debug.Print Result.Error.Message
End If
```

これで探索結果が取得できました。この時、 `Course/Price` の中に `Type = WithTeiki` があると、控除が発生しています。

```vb
Dim objCourse As Course
Dim objPrice As Price
Dim objLine As Line
For i = 0 To UBound(Result.Courses)
    objCourse = Result.Courses(i)
    For j = 0 To UBound(objCourse.Prices)
        objPrice = objCourse.Prices(j)
        If objPrice.Type = "WithTeiki" Then
            ' 控除あり
        End If
    Next j
Next i
```

控除があると、その際の区間情報が `fromLineIndex` と `toLineIndex` に格納されています。これを使って、どの区間が控除されたかを確認できます。 `fromLineIndex` と `toLineIndex` が同じ場合もあります。

```vb
Debug.Print objPrice.ToLineIndex ' 1
Debug.Print objPrice.FromLineIndex ' 2
' インデックスが1から始まるので、1を引いて0から始まるインデックスに変換
Debug.Print objCourse.Route.Lines(objPrice.ToLineIndex - 1).Name ' ＪＲ山手線外回り・池袋・上野方面
Debug.Print objCourse.Route.Lines(objPrice.FromLineIndex - 1).Name ' ＪＲ中央線快速・東京行
```

運賃については、 `Price.Kind = "FareSummary"` のデータを参照します。これには片道運賃や往復運賃が含まれています。

```vb
If objPrice.Kind = "FareSummary" Then
    Debug.Print objPrice.Oneway ' 150
    Debug.Print objPrice.Round ' 300
End If
```

## まとめ

一口に交通費精算と言っても、普段使っている定期があったりすると途端に計算が複雑になります。従業員の定期情報がデータ化されていれば、こうした算出も自動化が可能です。経費精算の効率化のために、駅すぱあとAPIをご利用ください。

さらにVBA SDKを使えば、Excel上で簡単に駅すぱあとAPIを利用できます。ぜひ試してみてください。

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