この記事は レコチョク Advent Calendar 2025 の13日目の記事となります。
はじめに
こんにちは、株式会社レコチョクで社内のDX化を推進している髙橋です。 今年の7月に、中学生の頃から応援している UNISON SQUARE GARDEN のファンクラブ10周年アニバーサリーライブが開催され、当然参加してきました。
ファンクラブ発足が10年前の7/24 日本武道館公演で発表され、私もその場にいたのですが あの時から10年間、同じ熱量で応援できていることに嬉しさを覚えます。
さて、レコチョクでは現在X-pointという電子申請のワークフローシステムで各種申請業務を行っています。 特定の部署では、月に100件以上もの申請書を起票する必要があり、工数がかかる上にオペミスのリスクが高い状態が続いていました。
改善方法を検討していく中で、X-pointがAPIを提供していることを知り、早速活用してみることにしました。
※下記に記載するコードはサンプルです
概要
ExcelVBAを使用し、以下の機能を実装した業務効率化ツール
- X-point REST API からのJSONデータ取得・加工
- Selenium によるブラウザ自動操作(Web画面ボタンクリック)
使用技術
環境
- Excel(Microsoft 365 Apps)
- VBA(Visual Basic for Applications)
API
外部ライブラリ・ツール
実装
処理の流れ
| ステップ | 処理 | 概要 |
|---|---|---|
| 1 | 今月起票対象の記入内容を取得 | 申請管理表から対象データを取得 |
| 2 | マスタ情報を取得 | X-point上のマスタ情報を取得(API) |
| 3 | 申請書を起票 | 申請フォームを立ち上げ、各フィールドへ申請内容を記入(API) |
| 4 | 申請書を下書き保存 | 申請フォームの「下書きボタン」を押下(Selenium Basic) |
| 5 | コメントを追記 | 下書き済みの申請書のコメントへ補足情報を追記 |
ステップ1:今月起票対象の記入内容を取得
Excel操作のみなので詳細は割愛
ステップ2:マスタ情報を取得
①HTTPリクエスト設定
- X-point API への接続を準備
マスタ毎に毎度実行するため、共通処理として定義
Set objHttp = HTTPリクエスト設定([URL])
Function HTTPリクエスト設定(URL As String)
Dim objHttp As Object
' HTTPリクエスト設定
Set objHttp = CreateObject("MSXML2.XMLHTTP")
objHttp.Open "GET", URL, False
objHttp.setRequestHeader "Authorization", "Bearer [トークン]"
objHttp.send
Set HTTPリクエスト設定 = objHttp
End Function
②既存データのクリア
- 前回取得したマスタ情報を削除
③レスポンスステータス確認
- API レスポンスが正常(200 OK)かチェック
- エラーの場合はメッセージを表示して中断
If objHttp.Status 200 Then
MsgBox "XXXXマスタの更新に失敗しました。" & vbCrLf & _
"管理者へお問い合わせください。" & vbCrLf & _
"エラーコード:" & objHttp.Status
Exit Sub
End If
④JSON パース
JsonConverter.basを使用してレスポンスを解析し VBA で扱えるオブジェクトに変換Set objJson = JsonConverter.ParseJson(objHttp.responseText)
⑤データ転記
- 配列をループしてシートに書き込み
- 主なパターン
- objJson(“Resources”)
- objJson(“master”)(“data”)
- objJson(“result”)(“items”)
実装する際は、まず API レスポンスをデバッグ出力 して構造を確認することをおすすめします。
row_ct = 2
For Each Var In objJson("master")("data")
ws_XXXXマスタ.Cells(row_ct, "A").Value = Var("XXXX_id")
ws_XXXXマスタ.Cells(row_ct, "B").Value = Var("XXXX_name")
row_ct = row_ct + 1
Next Var
ステップ3:申請書を起票
①処理対象リストを開く
②処理対象データを配列に読み込む
- 別ファイルの Excel から処理対象データを取得
③配列の内容をリクエストボディに変換する
- JSON 形式のリクエストボディ(単体のフィールド、表形式のフィールド)を構築
表形式のボディはDictionaryとCollectionを組み合わせてJSON形式を表現してみました。
Set fields = CreateObject("Scripting.Dictionary")
Set data = CreateObject("Scripting.Dictionary")
Set datas = New Collection
Set oFields = CreateObject("Scripting.Dictionary")
- リクエストボディ構築_単体フィールド
fields.Add "[単体フィールドID]", [記入する値]
- リクエストボディ構築_表形式フィールド
Set collection1 = New Collection
For i = 1 To UBound(処理対象_ary, 1)
For j = 1 To 10
Set dict1 = CreateObject("Scripting.Dictionary")
dict1.Add "[表形式フィールドID_1]", 処理対象_ary(i, [記入する値])
dict1.Add "[表形式フィールドID_2]", 処理対象_ary(i, [記入する値])
~ 他の明細フィールドも同様に処理 ~
collection1.Add dict1
Next j
Next i
fields.Add "[表のID]", collection1
④X-point API にPOSTリクエスト送信
multipart/form-data形式で送信
※ファイルアップロードなどで使われる HTTP のエンコード形式
data.Add "fields", fields
datas.Add data
oFields.Add "datas", JsonConverter.ConvertToJson(datas)
sBoundary = String(6, "-") & Replace(Mid(GenerateGUID, 2, 36), "-", "")
multipart/form-data形式のペイロード(実際に送信したいデータ本体)を構築
sPayLoad = "--" & sBoundary & vbCrLf & _
"Content-Disposition: form-data; name=""datas""" & vbCrLf & vbCrLf & _
JsonConverter.ConvertToJson(datas) & vbCrLf & _
"--" & sBoundary & "--"
- ADODB.Stream を使って文字列をバイナリに変換
※HTTP POST で UTF-8 エンコードされたデータを正確に送信するため
Dim stream As Object
Set stream = CreateObject("ADODB.Stream")
stream.Type = adTypeText
stream.Charset = "UTF-8"
stream.Open
ChangeStreamType stream, adTypeText
stream.WriteText sPayLoad
ChangeStreamType stream, adTypeBinary
stream.Position = 0
formData = stream.Read
stream.Close
- HTTP POST リクエストの送信(申請書を起票)
Set objHttp = CreateObject("MSXML2.XMLHTTP")
objHttp.Open "POST", "https://[X-pointクラウドURL]/xpoint/multiapi/v1/documents/docview", False
objHttp.setRequestHeader "Authorization", "Bearer [トークン]"
objHttp.setRequestHeader "Content-Type", "multipart/form-data; boundary=" & sBoundary
objHttp.send (formData)
※この時点では、必要事項が記入された申請書のウィンドウが立ち上がっただけの状態なので、下書き保存ボタン押下はSeleniumで実装
ステップ4:申請書を下書き保存
①レスポンスから URL を抽出
- 正規表現で下書きページの URL を取得
- 下書きボタンを自動押下(下書き起票が完了するまで3秒待機)
Set regex = CreateObject("VBScript.RegExp")
regex.Pattern = "
<a>"
Set matches = regex.Execute(objHttp.responseText)
URL = matches(0).submatches(0)
Call 下書きボタン押下(URL)
Sub 下書きボタン押下(URL As String)
Dim driver As New Selenium.ChromeDriver
Dim table As Object
Dim button As Object
driver.Get URL
Set table = driver.FindElementById([テーブルID])
Set button = table.FindElementById([ボタンID])
button.Click
Application.Wait (Now + TimeValue("00:00:03"))
driver.Quit
End Sub
ステップ5:コメントを追記
①対象の書類にコメントを追記
- コメントを追記する書類IDを指定する
json = "{""content"": """ & コメント & """, ""attentionflg"": 1}"
' コメント追加処理
Dim objHttp As Object
Set objHttp = CreateObject("MSXML2.XMLHTTP")
objHttp.Open "POST", "https://[X-pointクラウドURL]/xpoint/api/v1/documents/[書類ID]/comments", False
objHttp.setRequestHeader "Content-Type", "application/json"
objHttp.setRequestHeader "Authorization", "Bearer [トークン]"
objHttp.send (json)
まとめ
APIを使った開発は今回が初めてだったこともあり、大変身になる開発になりました。
更にブラッシュアップできる点(保守性の向上等)があるツールですので、自身も勉強も兼ねて少しずつ成長させていければと思います。
最後までお読みいただきありがとうございました。
明日の レコチョク Advent Calendar 2025 は14日目<【Android】Unityアプリをネイティブアプリに組み込んでみる>です。お楽しみに!
参考
高橋雄悟