by 庄司 里菜 | May 14, 2018

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

はじめに

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

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

PCA会計DXとは

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


詳しくは以下の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から取得することが可能です。


前提条件

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

  • 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アカウントでログインします。


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


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

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

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


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

  • アプリケーション名 : 任意のアプリケーション名を入力します。
  • 会社名 : 任意の会社名を入力します。
  • 説明 : 任意の説明文を入力します。
  • リダイレクトURL : http://localhost:33333 (33333ポートを別なアプリケーションで使用している場合は違うポートを指定してください)
  • アプリケーションURL : http://localhost:33333
  • プログラムID : cdata等任意のプログラムIDを入力します。
  • 使用するPCAのAPI : 「PCA会計DX」を選択します。



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


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

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の登録が必要となります。


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


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

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


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


OtherのProductCodeは会計DXの設定値を置いていますが、違うPCAアプリケーションを利用する場合は都度適切な値に書き換えてください。 また、DataAreaIDは試用版の環境となっているので、こちらも都度適切な値へ書き換えてください。

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

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

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


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


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


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


Tableauでの接続確認

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


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


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


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




 
 
ダウンロード