Edited at

PCA会計DXのデータをCData ODBC REST Driver + Tableauで可視化してみる

More than 1 year has passed since last update.


はじめに

基幹・会計システムのデータ分析・連係の需要はまだまだ尽きることがありませんが、各種アプリケーションが対応しているBIツールやETL/EAIツールは少ないのが実情かと思います。

そこで今回はPCAの会計ソフト、会計DXが公開しているWeb APIを用いて、CData ODBC REST Driver経由でBIツールのTableauとの連係を実現してみました。


PCA会計DXとは

ピー・シー・エー株式会社が提供する一般企業様向け会計ソフトです。

image.png

詳しくは以下のURLからどうぞ。

http://pca.jp/area_product/prokai.html

また、今回使用するPCA クラウド Web APIについては、以下のWebサイトで詳しく記載されています。

http://pca.jp/area_top/ltd/160411.html


実現イメージ

各BIツール(Tableau、QlikSence、PowerBI)からはODBCインタフェースでSQL(Select文)を発行するとCData REST ODBC Driverが、PCA会計DXのWebAPIのエンドポイントに対してHTTPリクエストでGetメソッドを発行します。

Jsonフォーマットで返ってきたデータセットをCData REST ODBC DriverがODBCインタフェースのResultsetに変換してBIツールに返します。

これにより、BIツールからアドホックにSQLによるリクエストがあったタイミングで最新のデータをPCA会計DXから取得することが可能です。

image.png


前提条件

本記事では以下のサービスや製品を使用しています。


  • PCA 会計DX クラウド版 (あらかじめインストールしておいてください)

  • CData REST ODBC Driver ※30日間の評価版あり

  • Tableau Desktop ※無料トライアル版あり

  • Googleアカウント(OAuth用アプリケーション登録をするために必要となります)


手順


PCA Web API 利用準備

PCA Web APIを利用する場合は、あらかじめ利用申請等が必要になるので、以下のWeb Siteから実施しておきます。

http://pca.jp/area_top/ltd/160411.html

申請後PCAクラウドアプリケーション利用用アカウントとして、ServiceユーザーIDとパスワード、招待コードが送られてくるので、控えておきましょう。

その上で、以下Webサイトにアクセスし、OAuthの認証を通すためにアプリケーション登録を行います。

https://pcadev.jp/DevelopersConsole/

Webサイトにアクセスすると、以下のような画面が表示されるので、任意のGoogleアカウントでログインします。

image.png

一番最初はアカウント登録をする必要があるので、各種情報を招待コードを入力し、[登録]をクリックします。

image.png

登録完了後、アプリケーションの管理画面へ遷移します。

この画面からOAuth認証用のアプリケーション登録を行い、認証に必要なClientID・ClientSecretを取得します。

それでは実際に[新規アプリケーションの作成]をクリックし、アプリケーション登録を行います。

image.png

以下の情報をそれぞれ入力し、[登録]をクリックします。


  • アプリケーション名 : 任意のアプリケーション名を入力します。

  • 会社名 : 任意の会社名を入力します。

  • 説明 : 任意の説明文を入力します。

  • リダイレクトURL : http://localhost:33333 (33333ポートを別なアプリケーションで使用している場合は違うポートを指定してください)

  • アプリケーションURL : http://localhost:33333

  • プログラムID : cdata等任意のプログラムIDを入力します。

  • 使用するPCAのAPI : 「PCA会計DX」を選択します。

image.png

登録完了後、クライアントIDとクライアントシークレットが表示されるので、控えておきます。

image.png

以上でアプリケーション登録は完了です。


REST データ RSDファイル

続いて、PCAのWeb APIをCData ODBC REST DeiverがSQLとして解釈できるように設定ファイルを作成します。

サンプルとしてPCA会計DXの仕訳伝票 (InputSlip)のデータを取得するための設定ファイルを作成していますので、以下のXMLを[InputSlip.rsd]というファイル名で保存して、利用してみてください。

保存先フォルダは後ほど使用するので「C:\CData_REST\PCA」といった書き込み可能な任意のフォルダに配置してください。

以下、InputSlip.rsdのサンプルです。


<rsb:script xmlns:rsb="http://www.rssbus.com/ns/rsbscript/2" xmlns:xs="http://www.w3.org/2001/XMLSchema">

<!-- See Column Definitions to specify column behavior and use XPaths to extract column values from JSON. -->
<rsb:info title="JSONData" desc="Generated schema file." xmlns:other="http://www.rssbus.com/ns/rsbscript/2/other">
<!-- You can modify the name, type, and column size here. The name must match the values in the rsb:script block below -->
<attr name="BEVersion" xs:type="integer" readonly="false" other:xPath="BEVersion" />
<attr name="CrBankTransferState" xs:type="string" readonly="false" other:xPath="{SubRepeatElement}/CrBankTransferState" />
<attr name="CrBuId" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/CrBuId" />
<attr name="CrHojoId" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/CrHojoId" />
<attr name="CrId" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/CrId" />
<attr name="CrKmkId" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/CrKmkId" />
<attr name="CrMoney" xs:type="double" readonly="false" other:xPath="{SubRepeatElement}/CrMoney" />
<attr name="CrReserve1" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/CrReserve1" />
<attr name="CrReserve2" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/CrReserve2" />
<attr name="CrReserve3" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/CrReserve3" />
<attr name="CrStamp" xs:type="string" readonly="false" other:xPath="{SubRepeatElement}/CrStamp" />
<attr name="CrTaxCalcMode" xs:type="string" readonly="false" other:xPath="{SubRepeatElement}/CrTaxCalcMode" />
<attr name="CrTaxClassId" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/CrTaxClassId" />
<attr name="CrTaxKmkId" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/CrTaxKmkId" />
<attr name="CrTaxMoney" xs:type="double" readonly="false" other:xPath="{SubRepeatElement}/CrTaxMoney" />
<attr name="DrBankTransferState" xs:type="string" readonly="false" other:xPath="{SubRepeatElement}/DrBankTransferState" />
<attr name="DrBuId" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/DrBuId" />
<attr name="DrHojoId" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/DrHojoId" />
<attr name="DrId" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/DrId" />
<attr name="DrKmkId" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/DrKmkId" />
<attr name="DrMoney" xs:type="double" readonly="false" other:xPath="{SubRepeatElement}/DrMoney" />
<attr name="DrReserve1" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/DrReserve1" />
<attr name="DrReserve2" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/DrReserve2" />
<attr name="DrReserve3" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/DrReserve3" />
<attr name="DrStamp" xs:type="string" readonly="false" other:xPath="{SubRepeatElement}/DrStamp" />
<attr name="DrTaxCalcMode" xs:type="string" readonly="false" other:xPath="{SubRepeatElement}/DrTaxCalcMode" />
<attr name="DrTaxClassId" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/DrTaxClassId" />
<attr name="DrTaxKmkId" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/DrTaxKmkId" />
<attr name="DrTaxMoney" xs:type="double" readonly="false" other:xPath="{SubRepeatElement}/DrTaxMoney" />
<attr name="JournalHeaderId" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/JournalHeaderId" />
<attr name="LabelId" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/LabelId" />
<attr name="LabelString" xs:type="unknown" readonly="false" other:xPath="{SubRepeatElement}/LabelString" />
<attr name="LineNumber" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/LineNumber" />
<attr name="Number1" xs:type="unknown" readonly="false" other:xPath="{SubRepeatElement}/Number1" />
<attr name="Number2" xs:type="unknown" readonly="false" other:xPath="{SubRepeatElement}/Number2" />
<attr name="RemId" xs:type="integer" readonly="false" other:xPath="{SubRepeatElement}/RemId" />
<attr name="Summary" xs:type="string" readonly="false" other:xPath="{SubRepeatElement}/Summary" />
<attr name="CrBankTransferState" xs:type="string" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/CrBankTransferState" />
<attr name="CrBuId" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/CrBuId" />
<attr name="CrHojoId" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/CrHojoId" />
<attr name="CrId" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/CrId" />
<attr name="CrKmkId" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/CrKmkId" />
<attr name="CrMoney" xs:type="double" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/CrMoney" />
<attr name="CrReserve1" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/CrReserve1" />
<attr name="CrReserve2" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/CrReserve2" />
<attr name="CrReserve3" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/CrReserve3" />
<attr name="CrStamp" xs:type="string" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/CrStamp" />
<attr name="CrTaxCalcMode" xs:type="string" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/CrTaxCalcMode" />
<attr name="CrTaxClassId" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/CrTaxClassId" />
<attr name="CrTaxKmkId" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/CrTaxKmkId" />
<attr name="CrTaxMoney" xs:type="double" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/CrTaxMoney" />
<attr name="DrBankTransferState" xs:type="string" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/DrBankTransferState" />
<attr name="DrBuId" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/DrBuId" />
<attr name="DrHojoId" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/DrHojoId" />
<attr name="DrId" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/DrId" />
<attr name="DrKmkId" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/DrKmkId" />
<attr name="DrMoney" xs:type="double" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/DrMoney" />
<attr name="DrReserve1" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/DrReserve1" />
<attr name="DrReserve2" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/DrReserve2" />
<attr name="DrReserve3" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/DrReserve3" />
<attr name="DrStamp" xs:type="string" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/DrStamp" />
<attr name="DrTaxCalcMode" xs:type="string" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/DrTaxCalcMode" />
<attr name="DrTaxClassId" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/DrTaxClassId" />
<attr name="DrTaxKmkId" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/DrTaxKmkId" />
<attr name="DrTaxMoney" xs:type="double" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/DrTaxMoney" />
<attr name="JournalHeaderId" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/JournalHeaderId" />
<attr name="LabelId" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/LabelId" />
<attr name="LabelString" xs:type="unknown" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/LabelString" />
<attr name="LineNumber" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/LineNumber" />
<attr name="Number1" xs:type="unknown" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/Number1" />
<attr name="Number2" xs:type="unknown" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/Number2" />
<attr name="RemId" xs:type="integer" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/RemId" />
<attr name="Summary" xs:type="string" readonly="false" other:xPath="InputSlipDataList/BEInputSlipData/Summary" />
<attr name="ApprovalAreaUserId1" xs:type="integer" readonly="false" other:xPath="InputSlipHeader/ApprovalAreaUserId1" />
<attr name="ApprovalAreaUserId2" xs:type="integer" readonly="false" other:xPath="InputSlipHeader/ApprovalAreaUserId2" />
<attr name="ApprovalAreaUserId3" xs:type="integer" readonly="false" other:xPath="InputSlipHeader/ApprovalAreaUserId3" />
<attr name="ApprovalAreaUserId4" xs:type="integer" readonly="false" other:xPath="InputSlipHeader/ApprovalAreaUserId4" />
<attr name="Date_SerializeTarget" xs:type="string" readonly="false" other:xPath="InputSlipHeader/Date/SerializeTarget" />
<attr name="HsId" xs:type="integer" readonly="false" other:xPath="InputSlipHeader/HsId" />
<attr name="Id" xs:type="integer" readonly="false" other:xPath="InputSlipHeader/Id" />
<attr name="InputAreaUserId" xs:type="integer" readonly="false" other:xPath="InputSlipHeader/InputAreaUserId" />
<attr name="InputModuleName" xs:type="unknown" readonly="false" other:xPath="InputSlipHeader/InputModuleName" />
<attr name="JournalClass" xs:type="string" readonly="false" other:xPath="InputSlipHeader/JournalClass" />
<attr name="LockType" xs:type="string" readonly="false" other:xPath="InputSlipHeader/LockType" />
<attr name="ManageClass" xs:type="string" readonly="false" other:xPath="InputSlipHeader/ManageClass" />
<attr name="Number" xs:type="integer" readonly="false" other:xPath="InputSlipHeader/Number" />
<attr name="OldId" xs:type="integer" readonly="false" other:xPath="InputSlipHeader/OldId" />
<attr name="OrgId" xs:type="integer" readonly="false" other:xPath="InputSlipHeader/OrgId" />
<attr name="Reserve1" xs:type="integer" readonly="false" other:xPath="InputSlipHeader/Reserve1" />
<attr name="Reserve2" xs:type="integer" readonly="false" other:xPath="InputSlipHeader/Reserve2" />
<attr name="Reserve3" xs:type="integer" readonly="false" other:xPath="InputSlipHeader/Reserve3" />
<attr name="ReserveMoney1" xs:type="double" readonly="false" other:xPath="InputSlipHeader/ReserveMoney1" />
<attr name="ReserveMoney2" xs:type="double" readonly="false" other:xPath="InputSlipHeader/ReserveMoney2" />
<attr name="ReserveMoney3" xs:type="double" readonly="false" other:xPath="InputSlipHeader/ReserveMoney3" />
<attr name="ReserveString1" xs:type="unknown" readonly="false" other:xPath="InputSlipHeader/ReserveString1" />
<attr name="ReserveString2" xs:type="unknown" readonly="false" other:xPath="InputSlipHeader/ReserveString2" />
<attr name="ReserveString3" xs:type="unknown" readonly="false" other:xPath="InputSlipHeader/ReserveString3" />
<attr name="State" xs:type="string" readonly="false" other:xPath="InputSlipHeader/State" />
<attr name="UpdateTime" xs:type="datetime" readonly="false" other:xPath="InputSlipHeader/UpdateTime" />
<attr name="VanishState" xs:type="boolean" readonly="false" other:xPath="InputSlipHeader/VanishState" />
<attr name="MainDrCrMode" xs:type="string" readonly="false" other:xPath="MainDrCrMode" />
<attr name="PermanentId" xs:type="integer" readonly="false" other:xPath="PermanentId" />
<attr name="SlipState" xs:type="string" readonly="false" other:xPath="SlipState" />
<attr name="TaxOrgMoneyCalcedByAs" xs:type="boolean" readonly="false" other:xPath="TaxOrgMoneyCalcedByAs" />
</rsb:info>

<rsb:set attr="outer.uri" value="[_connection.ServerURL][_connection.ApiVersion]/[_connection.ProductCode]/SelectDataArea" />
<rsb:set attr="outer.Method" value="POST"/>
<rsb:set attr="outer.ContentType" value="application/json" />
<rsb:set attr="outer.encodepostdata" value="false" />
<rsb:set attr="outer.Data">
{
"DataArea":"[_connection.DataAreaID]"
}
</rsb:set>
<rsb:set attr="outer.EnablePaging" value="True" />

<rsb:set attr="inner.uri" value="[_connection.ServerURL][_connection.ApiVersion]/[_connection.ProductCode]/Find/InputSlip" />
<rsb:set attr="inner.RepeatElement" value="/ArrayOfBEInputSlip/BEInputSlip" />

<rsb:set attr="inner.SubRepeatElement" value="/ArrayOfBEInputSlip/BEInputSlip/InputSlipDataList/BEInputSlipData" />
<rsb:set attr="inner.ContentType" value="application/json" />
<rsb:set attr="inner.header:name" value="Accept" />
<rsb:set attr="inner.header:value" value="application/json" />
<!-- The GET method corresponds to SELECT. Within the script block, you can see the URI modified to append a query string parameter. The results of processing are pushed to the schema's output. See SELECT Execution for more information. -->
<rsb:script method="GET">
<rsb:call op="jsonproviderGet" input="outer" output="firstOut">
</rsb:call>
</rsb:script>

<!-- The GET method corresponds to SELECT. Within the script block, you can see the URI modified to append a query string parameter. The results of processing are pushed to the schema's output. See SELECT Execution for more information. -->
<rsb:script method="GET">
<rsb:call op="jsonproviderGet" input="inner">
<rsb:push/>
</rsb:call>
</rsb:script>

</rsb:script>

RSDファイルの詳しい設定方法は下記URLのヘルプページに記載しています。

http://cdn.cdata.com/help/HWC/odbc/pg_rsbschemaintro.htm


CData ODBC REST Driverのインストール

TableauとPCA会計クラウドのAPIを繋ぐために必要となるCData ODBC REST Driverをインストールします。

CData REST ODBC Driverの30日間の評価版をダウンロードします。ダウンロードの際には、Emailの登録が必要となります。

image.png

ダウンロードしたsetup.exeファイルをBIツールがインストールされているマシンにインストールします。インストールウィザードに従い、EULAを確認したうえでインストールを完了します。

※途中、ライセンスサーバーへのオンラインアクティベーションが行われるためネットワーク環境に接続されている必要があります。

インストールが完了すると、ODBCのDSN設定のウィンドウが立ち上がります。

image.png

以下の項目をセットします。

OtherのProductCodeは会計DXの設定値を置いていますが、違うPCAアプリケーションを利用する場合は都度適切な値に書き換えてください。

また、DataAreaIDは試用版の環境となっているので、こちらも都度適切な値へ書き換えてください。

各種URLの接続先はEast02に設定しています。

「接続のテスト」ボタンをクリックするとOAuth認証のため事前に登録したアプリケーションの認証画面がブラウザで立ち上がります。

配布されている[サービスユーザーID][パスワード]を入力し、サービス認証をクリックします。

image.png

次に、PCA会計DXのユーザーアカウントの情報を入力し、ログオンを行います。

image.png

アクセス許可画面が表示されるので、内容を確認の上[データの利用を許可する]をクリックします。

image.png

OAuth Authorization Successful!の画面が表示されれば、認証完了です。

image.png


Tableauでの接続確認

Tableau Desktopを起動して、データ接続より「サーバーへ」>「詳細」>「その他データベース(ODBC)」を選択します。

image.png

「その他のデータベース(ODBC)」設定ウィンドウが開いたら、接続手段内のDSNから「CData REST Source」を選択して「サインイン」します。

image.png

「データソース」画面が開くので、左側のペインで、表「InputSlip (REST.InputSlip) (CData))」を選択して、右上のエリアにドラッグ&ドロップします。抽出を行い、右下のデータプレビューにPCA会計DXの仕訳伝票が表示されることを確認します。

image.png

あとはTableauの機能を利用して、各種グラフやマトリクスを作成することが可能です。

image.png