0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ZENITH Code実践⑥ 決算期と前期比を分析画面に加える

0
Posted at

「売上高が158億円」と分かったら、次に知りたくなるのは「前の期より増えたのか」です。ただ、前期比はいつでも出せる数字ではありません。前の期の値がない、決算期の長さが違う、前の期が赤字だった、といった場合には、計算はできても意味のある比較になりません。

今回は、実践⑤まで読んできた企業分析画面で、決算期を選ぶ処理と、前期比を出す条件・出さない条件を読みます。後半では、2社を同じ決算期で並べる「企業比較」の条件も確かめます。

対象決算期で2025-03 FYを選んだ画面。数値カードが2025-03期の売上高134億円・営業利益14.2億円・営業利益率10.6%と前期比に変わっている。企業名と数値は架空のサンプル

画面の企業と数値は架空のサンプルです。 実企業のデータへの切り替えは実践⑧で扱います。

私たち株式会社Crabgrassは、企業の財務データなどをAPIで提供するZENITH Codeを開発しています。本記事は自社サービスのデータを使うためのテンプレートを題材にした実装例です。

この記事のコードは、公開サンプル集のcompany-analysisテンプレート(執筆時点の版)に対応しています。起動方法は実践④の「ローカルで開く準備」と同じです。

1. 今回扱う画面と操作

操作 画面で変わるもの 今回読むコード
「対象決算期」で別の期を選ぶ 数値カード、期のバッジ、表と出典の印 reviewPeriod の change イベントと render()
数値カードの下の前期比を見る 「+17.9% 前期比」または「前期比較なし」 model.mjs の changeRate()
「企業比較」で共通の決算期を選ぶ 2社の棒と、比較条件の一致・不一致 renderComparison() と comparisonConditions()

2. 決算期を選ぶ

対象決算期のプルダウンは、データを読み込むたびに作り直しています。

if (!current.years.some(r => r.fiscalPeriod === selectedPeriod)) selectedPeriod = current.years.at(-1)?.fiscalPeriod ?? "";
$("reviewPeriod").replaceChildren(...[...current.years].reverse().map(r => node("option", `${r.fiscalPeriod} FY`, {value:r.fiscalPeriod})));
$("reviewPeriod").value = selectedPeriod;

1行目は、選んでいた期が今のデータにない場合に、一番新しい期を選び直す処理です。current.years は実践④で読んだ normalize() が古い順に並べているので、at(-1) が最新の期になります。別の企業に切り替えたときに、前の企業で選んでいた期が残って空の画面になることを防ぎます。

2行目では、配列を reverse() で新しい順にしてから選択肢を作っています。プルダウンの一番上に最新の期が来るようにするためです。元の current.years は書き換えず、[...current.years] で複製してから並べ替えています。reverse() は配列そのものを並べ替えるので、複製しないとグラフや表の期の順まで逆になってしまいます。

期を選び直したときの処理は1行です。

$("reviewPeriod").addEventListener("change",()=>{selectedPeriod=$("reviewPeriod").value;render();});

選んだ期を selectedPeriod に入れて、render() で画面全体を描き直します。render() の中では、数値カードの期を次のように決めています。

latest = years.find(r => r.fiscalPeriod === selectedPeriod) ?? years.at(-1)

名前は latest ですが、中身は「選んでいる期」です。数値カード、期のバッジ、表の列の色、出典の「•」は、どれもこの selectedPeriod を見ています。1つの値から全部を決めるので、カードは2025-03期なのに表の印は2026-03期、というずれが起きません。

グラフだけは、期を選んでも3期すべてを表示したままです。推移を見る場所なので、1期だけに絞ると比べる相手がなくなるためです。

3. 前期比を出す条件

数値カードの下の前期比は、model.mjs の changeRate() が計算します。

export function changeRate(current, previous, field) {
  if (!current || !previous || current.period !== "FY" || previous.period !== "FY" ||
      !current.accountingStandard || current.accountingStandard !== previous.accountingStandard ||
      current.fiscalPeriod.slice(5) !== previous.fiscalPeriod.slice(5) ||
      Number(current.fiscalPeriod.slice(0,4)) - Number(previous.fiscalPeriod.slice(0,4)) !== 1 ||
      !Number.isFinite(current.fiscalPeriodDays) || !Number.isFinite(previous.fiscalPeriodDays) ||
      current.fiscalPeriodDays < 360 || current.fiscalPeriodDays > 366 ||
      previous.fiscalPeriodDays < 360 || previous.fiscalPeriodDays > 366) return null;
  const a = finite(current[field]), b = finite(previous[field]);
  if (a === null || b === null) return null;
  if (field === "operatingMargin") return a-b;
  return b > 0 ? (a-b)/b : null;
}

条件が長く見えますが、確かめていることは次の表のとおりです。1つでも満たさなければ null を返し、画面には「前期比較なし」と表示します。

確かめること コード 満たさない例
前の期がある !previous 一番古い2024-03期を選んだ
どちらも通期 period !== "FY" 四半期の値が混ざった
会計基準が同じ accountingStandard 日本基準からIFRSへ変えた年
決算月が同じ fiscalPeriod.slice(5) 3月決算から12月決算へ変えた
ちょうど1年前 年の差が1 間の期のデータが欠けている
どちらも約1年 360〜366日 決算期の変更で9か月の期がある
どちらの値もある finite() 前の期の営業利益が未取得
前の期が正の値 b > 0 前の期が営業赤字

最後の「前の期が正の値」は、金額の増減率だけの条件です。前期が−4.2億円で今期が+6.1億円のとき、式どおりに計算すると「−245%」になります。業績は良くなっているのに、符号だけを見ると悪化したように読めてしまいます。こうした場合は、率を出さずに金額そのものを見たほうが誤解がありません。

営業利益率は a-b で、率の差を返します。12.5%と10.6%なら+1.9ポイントです。率同士の「増減率」(10.6%から12.5%は+18%)とは別の数字なので、画面では pt と書いて区別しています。

`${rate > 0 ? "+" : ""}${field === "operatingMargin" ? (rate*100).toFixed(1) + " pt" : percent(rate,lang)} ${t("yearChange")}`

rate > 0 のときだけ + を付けています。マイナスの数値は percent() が自分で - を付けるためです。

4. 「前期比較なし」になる例

架空クラウドに切り替えると、前期比が出るカードと出ないカードが並びます。

架空クラウドの2026-03期。売上高は+31%の前期比が出ているが、営業利益と営業利益率は「前期比較なし」

カード 2026-03期 2025-03期 結果
売上高 76億円 58億円 +31%
営業利益 6.1億円 未取得(null) 前期比較なし
営業利益率 8% 未取得(null) 前期比較なし

架空クラウドの2025-03期の営業利益は、実践④で見た欠損の例です。前の期の値がないので、営業利益の前期比は出せません。営業利益率もAPIの値が null なので同じです。

対象決算期で2025-03期を選び直しても、営業利益は「前期比較なし」のままです。今度は今期の値が欠損で、前の2024-03期は営業赤字です。どちらの理由でも、0円とみなして計算することはしません。

5. 2社を同じ決算期で比べる

「企業比較」では、選んでいる企業と別の企業を、同じ決算期で並べます。

企業比較。比較する企業に架空クラウド、共通の決算期に2026-03 FYを選び、決算期・会計基準・期間日数が一致していることと、売上高・営業利益・営業利益率の棒が表示されている

共通の決算期のプルダウンには、2社の両方にある期だけを並べます。

const common = other ? current.years.filter(a=>other.years.some(b=>b.fiscalPeriod===a.fiscalPeriod)) : [];

3月決算の会社と12月決算の会社を比べると、fiscalPeriod が一致する期がないので、共通の決算期は空になります。画面には「共通の決算期がありません。」と表示し、棒は描きません。決算月が違う会社同士では、同じ「2026年の通期」でも対象の月が9か月ずれているためです。

期が選べたら、comparisonConditions() で比べる条件をもう一度確かめます。

export function comparisonConditions(a, b) {
  return Boolean(a && b && a.period === "FY" && b.period === "FY" &&
    a.fiscalPeriod === b.fiscalPeriod && a.accountingStandard &&
    a.accountingStandard === b.accountingStandard &&
    Number.isFinite(a.fiscalPeriodDays) && a.fiscalPeriodDays > 0 &&
    a.fiscalPeriodDays === b.fiscalPeriodDays);
}

条件を満たすと「✓ 決算期・会計基準・期間日数が一致」、満たさないと「! 比較条件に差異・不明点あり」と表示します。条件が違っても棒は描きます。日本基準の会社とIFRSの会社を並べたいこともあるためです。そのかわり、会計基準と期間日数をそのまま表示して、違いがあることを読む人に伝えます。

model.mjs の関数の上には、次のコメントがあります。

// Matching metadata is a necessary check, not evidence of economic comparability.

決算期や会計基準がそろっていることは、比べるための最低限の確認です。業種や事業の構成が違えば、同じ営業利益率でも意味は変わります。画面の下にも「業種や事業構成の違いを調整した比較ではありません」と書いています。会社同士の比べ方は実践③でも扱いました。

6. 小さな変更で処理を確かめる

前期比に、増減の金額も並べてみます。「+17.9%」だけでは、どれくらいの金額が増えたのかが分かりにくいためです。

app.mjs の render() で、前期比の文字を作る1行を、次の3行に置き換えます。

const diff = rate === null || field === "operatingMargin" ? null : latest[field] - previous[field];
const amount = diff === null ? "" : `${diff > 0 ? "+" : ""}${money(diff, lang, true)}${t("hundredMillion")} / `;
const change = node("div", rate === null ? t("notComparable") : `${amount}${rate > 0 ? "+" : ""}${field === "operatingMargin" ? (rate*100).toFixed(1) + " pt" : percent(rate,lang)} ${t("yearChange")}`, {class:"kpi-change"});

rate が null でないときだけ金額を計算しています。changeRate() の条件を通った組だけが対象になるので、決算期の長さが違う期や、欠損の期の差を出してしまうことはありません。営業利益率は金額ではないので対象外にしています。

保存してブラウザを再読み込みすると、架空精密工業の2026-03期は次のように表示されます。

カード 変更前 変更後
売上高 +17.9% 前期比 +24億円 / +17.9% 前期比
営業利益 +39.4% 前期比 +5.6億円 / +39.4% 前期比
営業利益率 +1.9 pt 前期比 +1.9 pt 前期比

架空クラウドの2026-03期では、売上高は「+18億円 / +31% 前期比」になり、営業利益は「前期比較なし」のままです。

この変更でも、条件の判断は changeRate() に任せています。表示の側で別の条件を書き足すと、率は出ないのに金額だけ出る、といった食い違いが起きやすくなります。

7. 確認箇所

症状 確認箇所
期を選んでも数値カードが変わらない selectedPeriod に値が入っているか。render() を呼んでいるか
グラフや表の期の順が逆になった reverse() の前に配列を複製しているか
前期比がいつも「前期比較なし」 期の差が1年か。fiscalPeriodDays が入っているか
赤字から黒字の期で前期比が出ない 前の期が0以下のときは率を出さない仕様
共通の決算期が選べない 2社の決算月が同じか
比較の欄に「!」が出る 会計基準または期間日数が違う。表示された値を確認

コードをAIと一緒に変更する場合は、比べてよいかの判断をどこで行うかを指定すると、条件の二重管理を避けられます。

company-analysisテンプレートの数値カードで、前期比の前に増減額を表示してください。

対象は app.mjs の render() にある、前期比の文字を作る部分です。
model.mjs の changeRate() が null を返すときは、増減額も表示しないでください。
増減額は億円で表示し、プラスのときは + を付けます。営業利益率は対象外です。
changeRate() の条件や、null を 0 に置き換える処理は追加しないでください。
変更箇所と、架空精密工業・架空クラウドで確認する操作を説明してください。

8. 次回は見た目と操作

今回は、決算期を1つの値で管理し、前期比と企業比較に「出さない条件」があることを確かめました。次回のZENITH Code実践⑦では、テーマ、余白、文字の大きさ、スマホでの並び方、表示設定の保存など、画面の見た目と操作を整える部分を読みます。

ZENITH Code — 日本企業の財務データを、APIで。サービスサイトを見る

ZENITH Codeを見る · APIドキュメント

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?