【AppSheet】請求書を作ろう~シンプルver.~

【AppSheet】請求書を作ろう~シンプルver.~

はじめに

今回は請求書作成システムの開発を行ないます。

ひとくちに請求書といっても、様々な形式がありますが、今回作るのは『シンプルバージョン』です。

もちろん、シンプルバージョンと言っても、請求書として必要な項目はすべて揃っているのでご安心ください。

では、さっそく解説していきます!

完成イメージ

以下が完成した請求書作成システムのイメージです。

また、作成された請求書は以下です。

テーブルの設定

テーブルは以下の4つです。

①請求ヘッダ
②請求明細
③入金データ
④顧客データ
⑤検索用

以下、ひとつずつ説明していきます。

①請求ヘッダ

請求書の様な合計と明細が必要な書類は、ヘッダと明細の2つに分割します。

見積書や納品書なども同様ですので、これは1つ覚えておきましょう。

青文字はすべてバーチャルカラムです。

・ID
・請求日(Date)
・支払期限(Date)
・ステータス(Enum)
・顧客名(Ref)
・請求書発行回数(Number)
・PDF(File)
・Related 請求明細s(自動生成)
・Related 入金データs(自動生成)

・10%対象金額(Price)

SUM([Related 請求明細s][10%対象])

・8%対象金額(Price)

SUM([Related 請求明細s][8%対象])

・0%対象金額(Price)

SUM([Related 請求明細s][0%対象])

・請求金額(税込)(Price)

[10%対象金額] * 1.1 + [8%対象金額] * 1.08 + [0%対象金額]

・請求金額(税抜)(Price)

SUM([Related 請求明細s][金額])

・入金金額合計(Price)

SUM([Related 入金データs][入金金額])

・請求残高(Price)

[請求金額(税込)]-[入金金額合計]

・10%消費税(Price)

[10%対象金額]*0.1

・8%消費税(Price)

[8%対象金額]*0.08

・消費税合計(Price)

[10%消費税]+[8%消費税]

このテーブルのポイントは「消費税」です。

通常であれば、「消費税」というバーチャルカラムを1つ準備し、SELECTなどを使って計算結果を入れるのですが、ここでは各税区分ごとにカラムを作ってます。

理由は、SELECTを使ったバーチャルカラムは、将来的にデータが増えると重くなるためです。

特に、請求書のような数年にわたり保管義務のあるものはデータ量が莫大になるので、今回のような形式にした方が良いでしょう。

②請求明細

ヘッダを作成したら、次に請求明細を作ります。

それぞれの請求明細に請求ヘッダのIDを持たせることで、それぞれの明細を特定の請求ヘッダにまとめることができます。

カラムは以下の通りです。

・ID(Text)
・請求ヘッダ(Number)
・仕様(Text)
・個数(Number)
・単価(Price)
・税率(Enum)
・10%対象(Price)

IF([税率]="10%",[金額],0)

・8%対象(Price)

IF([税率]="8%",[金額],0)

・0%対象(Price)

IF([税率]="0%",[金額],0)

・備考(Text)
・金額(Price)

[個数]*[単価]

10%対象、8%対象、0%対象はFOMULAに関数を入力してください。

また、「税率」からむのEnumは「10%、8%、0%」の三つが選択肢です。

ここでとても重要なこととして、

「%」は必ず全角にしてください。

今回、「税率」カラムはテキストとして読み取らせますが、半角の%だと、勝手に百分率に変換されてしまいます。

そのため、%は必ず全角で表記するようにしてください。

③入金データ

・ID(Text)
・請求ヘッダ(Ref)
・入金日(Date)
・入金金額(Price)
・備考(Text)

④顧客データ

・ID(Text)
・顧客名(Text)
・住所(Text)
・担当者(Text)
・Related 請求ヘッダs(自動生成)
・Related 検索用s(自動生成)

⑤検索用

・ID(Text)
・開始日(Date)
・終了日(Date)
・顧客名(Ref)

「検索用」テーブルの使いどころは、次のUIのViewの設定で詳しく解説していきます。

Viewの設定

テーブルの設定が終わったら、次はビューの設定に入ります。

ビューの全体像は以下です(わかりやすくAppSheetの画像を添付します)

REFERENCE VIEWSにある3つのビューは、「ダッシュボード」ビューの構成要素になります。

「ダッシュボード」ビューの全体像と動きは以下です。

「検索」ビューで指定された条件で「請求ヘッダ」ビューがフィルターされ、「請求ヘッダ」ビューをクリックすると、その詳細が「請求ヘッダ詳細」ビューに表示されます。

それでは、REFERENCE VIEWSのビューから解説します。

「検索」ビュー

・View name:検索

・For this data:検索用

・View type:detail

View Optionsの「Quick edit columns」で「Add」をクリックし、開始日、終了日、顧客名を追加します。

この「Quick edit columns」、今回の検索機能で重要になります。

ここで選択した項目が、検索時に任意で値を変更できる箇所です。

「請求ヘッダ」ビュー

・View name:請求ヘッダ

・For this data:ダッシュボード請求ヘッダ
※スライスで新規につくります

・View type:deck

View Optionsの「Group by」は「請求日」の「Descending」とします。

スライスの作成

請求ヘッダビューでは、先で作成した「検索」ビューに応じて、表示内容をフィルターさせる必要があります。

このフィルターは、スライスによって制御していきます。

・スライス名:ダッシュボード請求ヘッダ

・Row filter condition

AND(
  IF(ISBLANK(検索用[検索用[開始日]]), TRUE, [請求日] >= INDEX(検索用[開始日], 1)),
  IF(ISBLANK(検索用[検索用[終了日]]), TRUE, [請求日] <= INDEX(検索用[終了日], 1)),
  IF(ISBLANK(検索用[顧客名]), TRUE, IN([顧客名], 検索用[顧客名]))
)

まず、ISBLANK()に関しては、未選択の状態を制御しています。

IFを使って、ISBLANK()の場合をTRUEとすることで、選択欄が未選択(空欄)の場合に、すべてのレコードを表示するようにしています。

次に、[請求日] >= INDEX(検索用[開始日], 1)は、開始日より後の請求日の請求ヘッダを表示します。

INDEXを使っている理由は、LIST形式からDate形式に変換するためです。

検索用[開始日]だけだと、List形式となってしまい、Date形式である[請求日]と型が一致しません。

そのため、INDEXを使うことで、List内にある任意の値(今回は[開始日])を抽出し、Date型である[請求日]と比較することができます。

IN()関数については、請求ヘッダの「顧客名」カラムから、検索用の「顧客名」と一致したものにTRUEを返す、という形です。

以上のようなスライスをつくることで、検索による動的な値変換が可能になります。

「請求ヘッダ詳細」ビュー

・View name:請求ヘッダ詳細

・For this data:ダッシュボード請求ヘッダ

・View type:detail

「ダッシュボード」ビュー

・View name:ダッシュボード

・View type:dashboard

View Optionの「View entries」は以下です。

・検索:Tall
・請求ヘッダ:Tall
・請求ヘッダ詳細:Large

また、Interactive modeは必ずONにしてください。

これをONにしておかないと、特定の請求ヘッダをクリックしても、「請求ヘッダ詳細」ビューが動的に動きません。

「顧客データ」

・View name:顧客データ

・For this data:顧客データ

・View type:table

これは顧客データを登録するためのViewなので、自由に設定してください。

以上で、Viewの設定は完了です。

請求書発行の設定

最後に、請求書を発行するための設定を行ないます。

順番としては、まず請求書のテンプレートの作成、次にアクションの設定、最後にBotの設定をしていきます。

テンプレートの作成

テンプレートについては、以下を参考にしてください。

https://docs.google.com/document/d/1vD0_f_zlhNV2MYkiYOCZXwFFV9jwKdBbQyRYZkgi0fE/edit?usp=sharing

テンプレートで重要なのは以下の3つです。

基本的な型(タグの差し込み)

<<[カラム名]>>

上記の型は、データの値を入力する際の型になります。

PDFの作成はBotを利用し、そのBotで指定したテーブルの値をPDFに書き込むことが可能です。

その書き込みの際に、上記の型を利用することで、特定の値を書き込むことができます。

例えば、<<[請求金額(税込)]>>となっている場合、この欄には「請求金額(税込)」カラムの値が入力されます。

参照先テーブルの型

<<[ Ref を設定したカラム名].[参照先テーブル内のカラム名 ]>>

テンプレートでは<<[顧客名].[顧客名]>>として記載されています。

説明をわかりやすくするため、<<[顧客名].[顧客名]>>と色分けをしてみました。

[顧客名]は、請求ヘッダのカラムです。これには参照先テーブルのIDが入っているため、<<[顧客名]>>とすると、IDが入力されてしまいます。

一方で、[顧客名]は、親テーブルである顧客テーブルの「顧客名」カラムです。

そのため、<<[顧客名].[顧客名]>>とすることによって、参照先の顧客名を取得することができます。

明細行の表示

請求ヘッダテーブルでは、「Related 請求明細s」という形で明細の一覧を取得できます。

AppSheetは便利なことに、以下の形式で書くことで、明細行の数に合わせた表を自動で作成してくれます。

<< Start: [ Related テーブル名s ]>>
<<[列名]>><<[列名]>><<[列名]>>...
<<End>>

今回作っているテンプレートであれば、表の最初である<<[仕様]>>にStartタグを含めて、最後の<<[金額]>>にEndタグを入れます。

そして、他の要素はStartタグとEndタグの間に入るように入れていきます。

アクションの設定

次に、アクションを設定していきます。

このアクションはBotを起動するためのアクションです。

Botは行の「追加」「削除」「更新」で起動させることができます。

今回は「更新」によってBotが起動するように設定するので、行を更新するアクションを作成します。

・Action name:請求書発行

・For record of this tabale:請求ヘッダ

・Do this:Data set the value of some columns in this row

・Set these columns:請求書発行回数=[請求書発行回数]+1

・Position :Primary

Do thisには、列を更新するアクションを設定します。

また、Set these columnsには具体的に実行するアクションの挙動を設定しています。

アクションを実行すると、カラム名「請求書発行回数」にある数値に+1されていきます。

これにより、行を更新するアクションができました。

Botの設定

最後に、Botの設定を行います。

左にあるナビゲーションの「+」をクリックし、「Create a new bot」をクリックします。

トリガーを設定する

「When this EVENT occurs」の「Configure event」をクリックし、「Create new event」を選択します。

・Event name:トリガー

・Table:請求ヘッダ

・Date chane type:Updates

・Condition:

[_THISROW_BEFORE].[請求書発行回数]<>[_THISROW_AFTER].[請求書発行回数]

ここで重要なのが、「Date change type」と「Condition」です。

「Date change type」はUpdatesを選択します。

これは、該当する行の値が更新されたときにBotを動かすという指示です。

続いて、「Condition」は更新時の条件を入力します。

今回の条件は、「[請求書発行回数]の前回の値と次回の値が変わったらBotを起動する」というものです。

つまり、[請求書発行回数]が1から2に変わった場合などに発火します。

この関数はBot利用時にはよく使うので、覚えておきましょう。

実行するBotを設定する

「Run this PROSESS」の「Add a step」をクリックします。

「Create new step」を選択したのち「New step」を「請求書発行」に変更します。

右側にある「Settings」では、「Create a new file」を選択します。

以下、その他の設定です。

・HTTP Content Type:PDF

・Template:紙のアイコンをクリックし、先で作ったテンプレートを選択

・File store:Ddeafault

・File Folder Path:

"請求書フォルダ"

・File Name Prefix:

[顧客名].[顧客名]&TEXT([請求日],"yyyymmdd")&"-"&[請求書発行回数]

・Disable Timestamp?:ON

・Attachment Page Orientation:Portrait

・Attachment Page Size:A4

・Use Custom Margins:OFF

File Folder Pathでは、作成したPDFファイルの保存先を指定できます。

AppSheetのプロジェクトが作られた時点で、デフォルトのファイル保存先が自動で指定されます。

基本的には「/appsheet/data/プロジェクト名」という形になっています。

ご自身のパスを確認したい場合は、「Settings」の「Infomation」にある「App Properties」の最下段を確認してみてください。

File Folder Pathは、このパス以降のフォルダを指定します。

今回の場合は、「請求書フォルダ」というフォルダを作り、そこに保存させたいので、「請求書フォルダ」を指定しています。

File Name Prefixでは、保存時にファイル名の指定ができます。

ポイントは、関数の最後にある[請求書発行回数]です。

AppSheetでファイルを同じ名前で保存した場合、フォルダ上は上書きされます。

しかし、キャッシュが残っているため、AppSheetからPDFファイルを開くと、上書き前のファイルが表示されます。

そのため、[請求書発行回数]をファイル名に含めることで、上書きではなく新規のファイルとして保存します。

これにより、上書き前のファイル表示を防ぐことができます。

PDFのパス名を保存

最後に、PDFのパス名を保存するBotを設定します。

「Add a step」をクリックし、「Create a new step」をクリックします。

「New step」を「PDFパス名保存」とし、「Run a task」を「Run a data action」に変更します。

「Set row values」を選択し、Set these column(s)では、「PDF」を選択します。

関数は以下の通りです。

"請求書フォルダ/"&[顧客名].[顧客名]&TEXT([請求日],"yyyymmdd")&"-"&[請求書発行回数]&".pdf"

これにより、カラム名「PDF」にパス名が保存されます。

完成後の動き

では、最後に完成後の動きを見てみましょう。

請求書の作成ができています。

ただ、レイアウトをもっと凝って行いたいという場合は、もう少し工夫が必要になります。

より複雑な請求書の作成方法は、また次回以降の記事で紹介しますので、ぜひ参考にしてみてください。