ブックをダウンロード
請求書トラッカーをダウンロードしてExcelで開きます。例示請求書、EUR/GBP/JPY/IDRのスナップショット、USD列、監査記録が入っています。
4つのシートを確認する
Invoice Trackerは請求書と数式、FX Snapshotsは日付付き観測値、Audit Trailは固定判断、Read Meは使い方と制限を示します。
元の通貨で請求書を追加する
青い入力セルにID、顧客、日付、通貨、税、レート日、ステータスを入力します。Net、Tax、Grossは請求書の通貨で入力します。
日付付き為替スナップショットを追加する
実際に使った履歴観測を追加し、日付、通貨、source、market_session、data_updated_at、レートを保存します。レートは1 USDあたりの請求通貨単位です。 EUR-20260602-v1のように一意のSnapshot IDを使い、IDがちょうど1行だけ存在し、スナップショットの通貨が請求書と一致することを確認する。修正はv2を新しい行に追加し、v1を上書きしない。data_updated_atは過去データが更新された時刻であり、effective_atとは別の項目である。
Representative historical responsecopy
{
"result": "success",
"base": "USD",
"date": "2026-06-02",
"source": "ecb_daily",
"sources": { "EUR": "ecb_daily" },
"market_session": "open",
"timestamp": "2026-09-08T11:52:18Z",
"data_updated_at": "2026-06-02T00:00:00Z",
"is_forward_filled": false,
"rates": { "EUR": 0.85844 },
"notice": "Indicative rates, not for settlement."
}数式で計算されたUSD列を確認する
日付と通貨をFX Snapshotsに照合し、金額をFX Rate / USDで割ります。スナップショットがない場合、USD列は空欄です。 数式は請求書100行目、スナップショット100行目まで入っている。拡張するときは両方を同時に広げる。Postedはラベルであり、セルをロックしたり数式を固定したりしない。
Excel formula · Net USDcopy
=IF(OR(F6<0,G6<0,H6<0,K6="",L6="Missing snapshot ID",L6="Duplicate snapshot ID",L6="Currency mismatch",L6="Invalid rate"),"",F6/K6)
計上済みの値を固定する
計上後はスナップショットを変更しません。訂正や再表示が必要なら新しい行を追加し、理由をAudit Trailに記録します。
Power Queryで新しいスナップショットを追加する
Power Queryスクリプトは指定した日付と通貨を取得します。共有ブックにAPIキーを保存しないでください。 Power Queryの出力はA:Iの9列である。まずstagingシートに読み込み、見出しを含めずデータ行だけを7行目以降へ値貼り付けする。Refresh Allは出力を置き換えるだけで履歴を追記しない。WindowsはData → Get Data → From Other Sources → Blank Query、対応するMicrosoft 365 for MacはData → Get Data → Launch Power Query Editorから開始する。認証はAnonymousを使い、キーが必要ならサーバー側proxyを使う。
Power Query M · explicit snapshotcopy
let
SnapshotDate = "2026-06-02",
Currency = Text.Upper(Text.Trim("EUR")),
Revision = "v1",
SelectedDate = Date.FromText(SnapshotDate, [Format = "yyyy-MM-dd", Culture = "en-US"]),
RelativePath = "v1/" & Date.ToText(SelectedDate, "yyyy-MM-dd") & "/USD",
Endpoint = "https://api.exchangerate.dev/" & RelativePath & "?symbols=" & Currency,
Payload = Json.Document(Web.Contents("https://api.exchangerate.dev", [
RelativePath = RelativePath,
Query = [symbols = Currency],
Timeout = #duration(0, 0, 0, 10)
])),
Source = if Payload[base] <> "USD" or Payload[date] <> SnapshotDate
then error "Unexpected response base or date" else Payload,
RawRate = Record.Field(Source[rates], Currency),
Rate = if not Value.Is(RawRate, type number) or RawRate <= 0
then error "Expected a positive numeric rate" else RawRate,
SnapshotId = Currency & "-" & Text.Replace(SnapshotDate, "-", "") & "-" & Revision,
Notes = "Response timestamp=" & Source[timestamp] & "; is_forward_filled=" &
(if Source[is_forward_filled] then "true" else "false"),
Snapshot = #table(
{"Snapshot ID", "Snapshot Date", "Currency", "Source", "Market Session", "Data Updated At (UTC)", "Rate / USD", "API Endpoint", "Notes"},
{{SnapshotId, SelectedDate, Currency, Record.Field(Source[sources], Currency), Source[market_session], Source[data_updated_at], Rate, Endpoint, Notes}}
)
in
Snapshot監査記録を残す
計上日、使用したスナップショット、source/session、固定理由を記録します。必要なら元のレスポンスも保管します。 Notesにはレスポンスのtimestampとis_forward_filledを残す。Snapshot ID、source、market_session、修正理由も記録する。
結果はレポート用に使う
これはレポートと分析の例です。税務、会計、コンプライアンス、決済の判断を行うものではありません。 例では100行目まで対応する。行を増やす場合は数式と検索範囲を一緒に拡張する。