2024/04/08

つないでみよう:#13)インボイス API で登録番号をチェック

WebAPI 連携日記の第 13 回です。今回はいよいよ国税庁のインボイス API に接続する機能をノーツに組み込みます。


まずは、完成イメージです。

【検索】ボタンをクリックすると、入力した登録番号でインボイス API に接続し、検索結果を入手します。ヒットするとそこから登録名称を取得して画面に確認メッセージを表示します。


スクリプトライブラリの作成

フォーム内で使用する LotusScript エディタは仕様が古く使いずらいので、メインのプログラムはスクリプトライブラリに作成します。新たに lsInvoice ライブラリを作成して、開発をはじめます。

メインルーチン GetInvoiceName は登録番号を引数にコールするとインボイス API 経由で名称を返す関数です。事前に入手したアプリケーション ID は定数宣言しています。

Option Declare
Private Const xAPPLICATION_ID = "????????"    'アプリケーション ID
Public Const pcsERROR = "ERROR"

Public Function GetInvoiceName(ByVal vsInvoiceNumber As String) As String
   Dim ns As New NotesSession
   Dim sURL As String
   Dim http As NotesHTTPRequest
   Dim jnav As NotesJSONNavigator

   On Error GoTo Proc_Err

   'HTTP リクエストの準備
   Set http = ns.CreateHTTPRequest()

   'URL 作成
   sURL = "https://web-api.invoice-kohyo.nta.go.jp/1/num"
   sURL = sURL & "?id=" & xAPPLICATION_ID
   sURL = sURL & "&number=" & vsInvoiceNumber
   sURL = sURL & "&type=21&history=0"

   'API コール
   http.PreferJSONNavigator = True
   Set jnav = http.Get(sURL)

   '1件目の登録名称を取得
   GetInvoiceName = xGetInvoiceName_Nth(jnav, 1)

Proc_Exit:
   Exit Function

Proc_Err:
   GetInvoiceName = pcsERROR
   Resume Proc_Exit
End Function

API コールは単純です。登録番号をアプリケーション ID を使って URL を完成させます。API のレスポンスは NotesJSONNavigator オブジェクトで受け取ります。


1 件目の登録名称を取得する処理はサブ関数化しています。

関数化にあたっては、2つ目の引数で何件目の結果を利用するかを指定できるようにしました。今回は 1 で固定なんですけどね...

Function xGetInvoiceName_Nth(vjnav As NotesJSONNavigator, ByVal viIndex As Integer) As String
   Dim iCount As Integer
   Dim je As NotesJSONElement
   Dim ja As NotesJSONArray
   Dim jobj As NotesJSONObject

   'レスポンスの件数を取得
   Set je = vjnav.GetElementByName("count")
   iCount = CInt(je.Value)

   'エラーチェック
   If iCount = 0 Then Exit Function
   If iCount < viIndex Then Exit Function

   '引数で指定したレスポンスを取得
   Set je = vjnav.GetElementByName("announcement")
   Set ja = je.Value
   Set je = ja.GetNthElement(viIndex)

   '登録名称を取得
   Set jobj = je.Value
   Set je = jobj.GetElementByName("name")
   xGetInvoiceName_Nth = je.Value
End Function

はじめにレスポンスの件数を取得して、ヒットしたのか、引数の指定は結果の件数を越えていないか判定しています。それ以降が処理の本体ですね。

レスポンスの JSON の構造は 前回 紹介しています。必要に応じてご確認ください。

処理では、まず announcement エレメントを取得します。この値は配列なので、NotesJSONArray の変数に代入し、メソッド GetNthElement で引数で指定した結果を取得します。これを NotesJSONObject の変数に代入しています。これは、 GetElementByName メソッドで name エレメントを取得するためです。

NotesJSON* のプログラムでは、うまく利用すれは見やすいコードが書けますが、代入が多く、データ構造を把握してからでないと処理内容が把握しにくそうです。コメントを添えてカバーしておくべき点ですね。


エラー処理

インボイス API では、入力した登録番号の桁数が足りないと API コール時にエラーが発生します。

   Set jnav = http.Get(sURL)     ’ ← ここでエラーが発生

そこで GetInvoiceName 関数にはエラー処理を設定しています。エラーを検出したら処理を Proc_Err に飛ばし、戻り値に定数宣言済みの pcsERROR をセットして関数を抜けます。これで呼び出し元にエラーを伝えます。

Public Const pcsERROR = "ERROR"
Public Function GetInvoiceName(ByVal vsInvoiceNumber As String) As String
  ・・・
   On Error GoTo Proc_Err
  ・・・
   '1件目の登録名称を取得
   GetInvoiceName = xGetInvoiceName_Nth(jnav, 1)
  ・・・

Proc_Exit:
   Exit Function

Proc_Err:
   GetInvoiceName = pcsERROR
   Resume Proc_Exit
End Function


フォームの作成

テスト用のフォームを作成します。

登録番号と登録名称のフィールドを編集可能フィールドで作成し、事前に作成したスクリプトライブラリを呼び出します。

[検索]ボタンのコードは以下の通りです。

はじめに入力した登録番号から名称を取得しています。

取得できた場合は、確認メッセージを表示します。[はい]で了承したときのみ bOk に True をセットします。

Sub Click(Source As Button)
   Dim nuiw As New NotesUIWorkspace
   Dim nuid As NotesUIDocument
   Dim nd As NotesDocument
   Dim sName As String
   Dim iMsg As Integer
   Dim sMsg As String
   Dim bOk As Boolean

   Set nuid = nuiw.CurrentDocument
   Set nd = nuid.Document

   'API に接続し登録名称を取得
   sName = GetInvoiceName(nd.Number(0))

   '結果の確認
   bOK = False
   If sName = "" Then
      sMsg = "一致する登録情報はありませんでした。" & Chr(10)
   Elseif sName = pcsERROR Then
      sMsg = "API 接続でエラーが発生しました。" & Chr(10) & "桁数など"
   Else
      iMsg = Messagebox("『" & sName & "』で正しいですか?", 36)
      If iMsg = 6 Then bOk = True
   End If

   '結果の処理
   If bOk Then
      '登録名称に反映
      Call nuid.GotoField("Name")
      Call nuid.FieldSetText("Name", sName)
   Else
      '登録番号入力の継続
      Call nuid.GotoField("Number")
      Call nuid.SelectAll
      sMsg = sMsg & "登録番号を確認してください。"
      Msgbox sMsg, 16
   End If
End Sub

結果の処理は bOk により分岐しています。

True では、取得した登録名称をフィールドに代入し、そこにカーソルを移動しています。

False の場合は、入力を継続することになるので、カーソルを登録番号に移動しています。また、再入力を強調するために、入力した番号を選択(反転)状態にしてから、メッセージを表示しています。


前回 連載:つないでみよう 次回


0 件のコメント:

コメントを投稿