• #Vue.js
  • #TypeScript
  • #連結会計
  • #UI/UX
  • #ハイライト機能
開発eurekapuメモ

連結精算表のナビゲーション・ハイライト機能を強化した実装記録

連結精算表ビューアの操作性を向上させるため、2つのハイライト機能を実装した。

  1. S/S(株主資本等変動計算書)→精算表へのセルレベルハイライト
  2. 注釈(※マーカー)クリック時の持分計算表セルハイライト

背景と目的

連結精算表の学習ツールでは、ユーザーが数値の関連性を追跡できることが重要になる。

例えば、S/Sの「当期純利益」行をクリックしたとき、精算表のどの行が対応しているかをハイライトで示したい。また、解説文中の注釈(※1, ※2など)をクリックしたとき、持分計算表のどのセルがその計算に関係しているかを視覚的に示したい。

機能1: S/S → 精算表のセルレベルハイライト

課題

S/Sの変動項目(当期純利益、配当など)は、精算表のBS/SS行と対応している。しかし、S/Sの表示ラベル(例: 「親会社株主に帰属する当期純利益」)と精算表の行名(例: 「当期純利益」)が異なるケースがあった。

従来の実装では row.label をそのままハイライト対象の行名として使用していたため、名称が一致せずハイライトが機能しないケースがあった。

解決策

SsRow 型に linkRowCode 属性を追加し、S/Sの表示ラベルとは別に精算表の行を特定するコードを指定できるようにした。

types.tsの変更

export interface SsRow {
  label: string
  values: (number | null)[]
  isSummary?: boolean
  isSubtotal?: boolean
  indent?: boolean
  linkSheet?: string
  linkColumnId?: string
  linkRowCode?: string  // 追加: 精算表の行を特定するコード
}

handleSsClickの修正

ConsolidatedFsTable.vuehandleSsClick 関数に rowCode 引数を追加。

function handleSsClick(row: SsRow) {
  if (row.linkSheet && row.linkColumnId) {
    // linkRowCodeがあればそれを使い、なければrow.labelをフォールバック
    const rowCode = row.indent ? (row.linkRowCode ?? row.label) : undefined
    emit('navigate-highlight', row.linkSheet, row.linkColumnId, rowCode)
  } else if (row.linkSheet) {
    emit('navigate-sheet', row.linkSheet)
  }
}

ポイント:

  • row.indent がtrueの場合のみ行レベルのハイライトを行う(期首残高・期末残高などの集計行はindent=falseなので列全体をハイライト)
  • linkRowCode が指定されていれば優先使用、なければ label をフォールバック

データファイルの更新(14ファイル)

各データセットの ssTableData で、表示ラベルと精算表の行名が異なる行に linkRowCode を追加。

// worksheet-data.ts の例
{
  label: '親会社株主に帰属する当期純利益',
  values: [0, 0, ni, ni, 0, ni],
  indent: true,
  linkSheet: 'worksheet-sum',
  linkColumnId: 'aje-total',
  linkRowCode: '当期純利益'  // 精算表の行名と一致させる
}

対象ファイル一覧:

  • worksheet-data.ts
  • worksheet-data-year2.ts
  • worksheet-data-additional-acq.ts
  • worksheet-data-step-acquisition.ts
  • worksheet-data-step-acq-30-80.ts
  • worksheet-data-equity-method-30-40.ts
  • worksheet-data-equity-method-10-30.ts
  • worksheet-data-equity-method-10-30-simple.ts
  • worksheet-data-partial-sale-80-70.ts
  • worksheet-data-partial-sale-80-20.ts
  • worksheet-data-partial-sale-80-10.ts
  • worksheet-data-partial-sale-80-70-20.ts
  • worksheet-data-full-sale-80-0.ts
  • worksheet-data-partial-sale-tax.ts

テストの追加

linkRowCode が精算表の行名と一致することを検証するテストを追加。

const verifySsRowCodeMapping = (
  datasetName: string,
  ssTableData: SsTableData | undefined,
  rows: AccountRowType[],
) => {
  if (!ssTableData) return

  const bsSsRows = rows.filter(r => r.section === 'bs' || r.section === 'ss')

  describe(`ssTableData indent行のlinkRowCode検証(${datasetName}`, () => {
    const indentRowsWithLink = ssTableData.rows.filter(r => r.indent && r.linkSheet)

    for (const row of indentRowsWithLink) {
      const rowCode = row.linkRowCode ?? row.label
      it(`"${row.label}" のrowCode "${rowCode}" が精算表のBS/SS行名に存在する`, () => {
        const matchingRow = bsSsRows.find(r => r.code === rowCode || r.name === rowCode)
        expect(matchingRow, `"${rowCode}" に一致するaccountRowが見つかりません`).toBeDefined()
      })
    }
  })
}

// 全データセットに対してテスト実行
verifySsRowCodeMapping('year1', year1Dataset.ssTableData, accountRows)
verifySsRowCodeMapping('year2', year2Dataset.ssTableData, accountRowsY2)
// ... 他のデータセット

機能2: 注釈クリック時の持分計算表セルハイライト

概要

解説文中の注釈(例: ※1, ※2)をクリックすると、関連する持分計算表のセルがハイライトされる機能を実装した。

型定義の追加

CommentaryNote 型に equityHighlight 属性を追加。

export interface CommentaryNote {
  marker: string        // "※1", "※2" など
  text: string          // 注釈の説明文
  equityHighlight?: { cells: [number, number][] }  // ハイライト対象セル [行, 列]
}

JournalCategoryTable.vueの実装

注釈クリック時のイベントハンドリングを実装。

const activeNoteMarker = ref<string | null>(null)

const handleNoteClick = (note: { marker: string; equityHighlight?: { cells: [number, number][] } }) => {
  if (!note.equityHighlight) return

  // トグル動作: 同じ注釈を再度クリックするとハイライト解除
  if (activeNoteMarker.value === note.marker) {
    activeNoteMarker.value = null
    emit('note-equity-highlight', null)
  } else {
    activeNoteMarker.value = note.marker
    emit('note-equity-highlight', note.equityHighlight.cells)
  }
}

テンプレート側では、クリック可能な注釈にスタイルを適用。

<p
  v-for="(note, ni) in section.notes"
  :key="ni"
  class="commentary-note"
  :class="{
    'note-clickable': !!note.equityHighlight,
    'note-active': activeNoteMarker === note.marker
  }"
  @click="handleNoteClick(note)"
>
  <span class="note-marker">{{ note.marker }}</span> {{ note.text }}
</p>

EquityCalcTable.vueのセル単位ハイライト対応

highlightCells プロパティを追加し、セル単位のハイライトに対応。

const props = defineProps<{
  table: EquityCalcTable
  highlightColumns?: number[]
  highlightRows?: number[]
  highlightCells?: [number, number][]  // 追加: セル座標の配列
}>()

const isCellHighlighted = (row: number, col: number): boolean => {
  // highlightCellsが指定されていれば優先
  if (props.highlightCells?.length) {
    return props.highlightCells.some(([r, c]) => r === row && c === col)
  }
  // フォールバック: 列・行の交差でハイライト
  return !!props.highlightColumns?.includes(col) && !!props.highlightRows?.includes(row)
}

親ページでの状態管理

[...slug].vue で注釈ハイライト状態を管理し、EquityCalcTableに渡す。

const noteHighlightCells = ref<[number, number][] | null>(null)

const handleNoteEquityHighlight = (cells: [number, number][] | null) => {
  noteHighlightCells.value = cells
}
<EquityCalcTable
  :table="currentDataset.equityCalcTable"
  :highlight-columns="currentEquityHighlight?.columns"
  :highlight-rows="currentEquityHighlight?.rows"
  :highlight-cells="noteHighlightCells ?? undefined"
/>

データファイルでのequityHighlight指定例

{
  id: 'sale-partial',
  name: '一部売却',
  entries: [...],
  commentary: [{
    title: '計算根拠',
    paragraphs: [...],
    notes: [
      {
        marker: '※1',
        text: 'X5年3月期開始仕訳76,020(※5)+ NCI帰属NI 800 + のれん償却1,320 + S社株式売却益修正5,000 = 83,140',
        equityHighlight: { cells: [[1, 0], [1, 1], [8, 1], [1, 3], [8, 3]] }
      },
      {
        marker: '※2',
        text: '支配獲得時のれん13,200 − 償却1,320 × 2 = 10,560',
        equityHighlight: { cells: [[8, 0], [8, 1], [8, 3], [8, 4]] }
      },
    ]
  }]
}

CSSスタイル

注釈のクリック可能状態とアクティブ状態を視覚的に示すスタイルを追加。

.note-clickable {
  cursor: pointer;
  border-radius: 4px;
  padding: 0.125rem 0.25rem;
  margin: 0 -0.25rem;
  transition: background-color 0.15s;
}

.note-clickable:hover {
  background: #fef9c3;  /* 薄い黄色 */
}

.note-active {
  background: #fef08a;  /* 濃い黄色 */
}

.note-active .note-marker {
  color: #b45309;  /* オレンジ */
}

持分計算表のセルハイライト。

.cell-highlight {
  background: #fef08a;
  font-weight: 700;
}

動作確認

  1. S/Sの「親会社株主に帰属する当期純利益」行をクリック
  2. 精算表の「当期純利益」行がハイライトされる
  3. 仕訳解説の「※1」をクリック
  4. 持分計算表の該当セル(複数)がハイライトされる
  5. 「※1」を再度クリックするとハイライト解除

まとめ

  • linkRowCode 属性により、S/Sの表示ラベルと精算表の行名が異なる場合でも正確にハイライトできるようになった
  • equityHighlight 属性により、解説文中の注釈から持分計算表の計算根拠セルを視覚的に示せるようになった
  • テストを追加し、データの整合性を自動検証できるようにした