XLSX の作成、編集、分析
| タスク | アプローチ |
|---|---|
| 作成または編集(数式・書式あり) | openpyxl — 下記の注意点を参照 |
| 一括データの入出力 | pandas(read_excel、to_excel) |
| シートのクイック確認 | markitdown file.xlsx — シートごとに ## SheetName を出力。.xlsm も読み取り可能。セル座標は出力しないため、これを元に編集計画を立てないこと |
| モデルの読み取り(数式 と 値の両方) | 2回の load_workbook パス — 下記の注意点を参照 |
openpyxl、pandas、markitdownはプリインストールされています —pip installを実行せずに、スクリプトを書いて直接インポートしてください。インポートが失敗した場合(またはmarkitdownコマンドがない場合)のみ、pip installで不足パッケージをインストールしてください。
以下のスクリプトパスは、このスキルのディレクトリからの相対パスです。
すべての出力に対する要件
- プロフェッショナルフォント(Arial、Times New Roman)を全体で使用すること。ユーザーが別途指定した場合を除く。
- 数式エラーをゼロにすること。
recalc.pyがerrors_foundを報告している状態で決して納品しないでください。エラーが自分より前から存在していたと思われる場合は、その証拠を示すこと:data_only=Trueで元のファイルを読み込み、該当セルを確認してください。自分が導入したエラーは、引き継いだエラーとまったく同じように見えます。 - 数式を使用し、ハードコードされた結果は使わないこと。
sheet['B10'] = '=SUM(B2:B9)'と書き、Python で計算した合計値を書かないでください。シートは入力値が変わったときに再計算されなければなりません。 - ユーザーの仕様を文字通りに従うこと。 正確なタブ名、正確な列ヘッダー、ユーザーが指定した数式。別の計算をするような再設計は、どんなに洗練されていても失敗です。
- すべての前提条件とハードコードされた数値を、読み手が確認できる場所に文書化すること — セルコメント、または表の末尾の隣接セルに。実在するソースがある場合はそれを引用すること(
ソース:Company 10-K、FY2024、45ページ、収益注記、[SEC EDGAR URL])。数値がユーザーから提供された場合は、その旨を明記すること。 - ユーザーが後で記入するためにあなたが作成するワークブックには、どのセルを編集すべきかを示す短い凡例と、期待される形式を示す現実的な値のサンプル行を1行含めること。編集を依頼されたファイルには、そのような行を決して追加しないでください。
- 既存ファイルを編集する場合:そのファイルの規則に完全に従うこと。 それらはここにあるすべてのガイドラインよりも優先されます。まず指定された入力セルを見つけてください — 異なるフォント色、塗りつぶし、または網掛けでマークされています — そこだけに書き込み、既存の数式には一切触れないでください。
再計算(ファイルに数式が含まれる場合は必須)
openpyxl は数式をキャッシュ値なしの文字列として書き込みます。再計算を行わない限り、すべての数式セルはキャッシュ値を読み取るもの(pandas、load_workbook(data_only=True)、ほとんどのプレビューア)に対して None と返ります。
python scripts/recalc.py output.xlsx [タイムアウト秒数] # デフォルト 30
LibreOffice がすべての数式を計算し、ファイルはその場で上書きされ、JSON が返ります:status(success | errors_found)、total_formulas、total_errors、およびエラータイプごとに最大100セルを指定する error_summary(locations_truncated は保留した数を示します — total_errors を信頼し、リストの長さを信頼しないでください)。指定されたセルを修正し、再度実行してください。status の代わりに error キーを持つ JSON は、何も再計算されなかったことを意味し、その場合のみ終了コードが非ゼロになります — errors_found は終了コード0で終了するため、正常終了をクリーンなワークブックと見なさないでください。
再計算が成功した緑色の結果は、数式が評価されたことを証明するだけで、正しいことを証明するわけではありません。 範囲が1つずれていたり、間違った行を参照していたりすると、エラーのないクリーンなファイルで間違った数値が出力されます。最初に2~3個の数式を書いて、期待通りの値を取得していることを確認してから、グリッド全体を構築してください。
別のファイルを参照するワークブックは、openpyxl で再保存して再計算すると、それらのリンクが失われます。そのような数式は ='[1]Returns Analysis'!$B$2 のように読み取られます — [1] はワークブックの外部参照リストへのインデックスであり、ディスク上の別ファイルを指すもので、シートではありません。そのファイルはほとんどの場合ここには存在しないため、セルのキャッシュ値だけがデータを保持しています。openpyxl は保存時にその値を削除し、LibreOffice は実際に参照を解決しようとして失敗し、#NAME? を書き込み、すべてのリンクを削除します。recalc.py はその状態では実行を拒否します — 上書き保存する前に、それらのセルの値を元のファイルからコピーしておいてください(--force で上書きし、損失を受け入れます)。
検証を通過する数式の選び方
LibreOffice は Excel よりも少ない関数しか実装しておらず、評価できない関数は文字通りの #NAME? として納品ファイルに焼き付けられます。
- Excel 2007 時代の関数を優先すること —
SUMIFS、INDEX、MATCH、IFERROR、SUMPRODUCT— これらはプレフィックス不要です。 - 6つの2007年以降の関数は、
_xlfn.プレフィックスを付ければ動作します。openpyxl は数式をそのまま XML に書き込み、Excel は2007年以降の関数名をプレフィックス付きで保存する(UI ではプレフィックスが隠される)ためです:_xlfn.TEXTJOIN、_xlfn.CONCAT、_xlfn.IFS、_xlfn.SWITCH、_xlfn.MAXIFS、_xlfn.MINIFS。裸で書くと、それぞれ#NAME?になります。 XLOOKUP、XMATCH、SORT、FILTER、UNIQUE、SEQUENCEは決して使用しないこと。 ランタイムの LibreOffice はどのプレフィックスでもこれらを評価できません。新しいビルドでは評価できますが、これらはスピル配列関数であり、openpyxl で書かれたファイルにはスピルメタデータがないため、範囲の左上のセルだけに値が入ります — そしてrecalc.pyは切り詰められた結果に対してtotal_errors: 0を報告します。ルックアップにはINDEX/MATCHを使用し、並べ替え、フィルター、重複除去は Python でセルを書き込む前に行ってください。- LibreOffice が解析できなかった数式は小文字で書き戻されます —
#NAME?の横にある素早い手がかりです。
openpyxl の注意点
- モデルの読み取りには2回のロードが必要です。
data_only=Trueはキャッシュされた値を返し、数式は消えます。デフォルトでは数式文字列を返し、値はありません。1回のパスで両方を得ることはできません。 data_only=Trueは、保存すると破壊的です。 そのワークブックには数式が残っていないため、保存するとすべての数式がリテラル値に置き換えられます — 永続的に。- openpyxl が書き込んだばかりのファイルに対して
data_only=Trueを使用すると、すべてNoneを返します — 最初にrecalc.pyを実行してください。(結果が""である数式もNoneと読み取られます。) - 結合セル:左上のアンカーだけに書き込むこと。 範囲内の他のすべてのセルは
MergedCellであり、.valueは読み取り専用です。 .xlsmはkeep_vba=Trueをload_workbookに渡さないとマクロが失われます。- スペースを含むシート名は、シート間参照で引用符で囲む必要があります:
='Assumptions Inputs'!$B$5。引用符なしだと#VALUE!と評価されます。
財務モデル
ユーザーが別途指定した場合、または既存のファイルがすでに別のことをしている場合を除きます。
色: ハードコードされた入力値とシナリオレバーは青色文字(0,0,255)· 数式は黒色 · 別シートへのリンクは緑色(0,128,0)· 別ファイルへのリンクは赤色(255,0,0)· 主要な前提条件とユーザーが記入すべきセルは黄色の塗りつぶし(255,255,0)。
数値: 通貨 $#,##0、単位はヘッダーに記載(Revenue ($mm))· ゼロは - で表示(パーセンテージも含む、$#,##0;($#,##0);-)· 負の数は括弧内 · パーセンテージ 0.0%、小数として保存(0.15 は 15.0% と表示;15 を保存すると 1500.0% と表示)· 評価倍率 0.0x · 年はテキストとして("2024"、決して 2,024 としない)。
構造: すべての前提条件を独自のラベル付きセルに配置し、それを使用する数式から参照する(=B5*(1+$B$6)、決して =B5*1.05 としない)· すべての予測期間にわたって一貫した数式(行途中の単一編集セルが最も一般的な静かなエラー)· ゼロになり得る分母をガードする。
依存関係
openpyxl、pandas、markitdown(pip、プリインストール — インポートが失敗したかコマンドがない場合のみインストール)· LibreOffice(soffice、サンドボックス環境向けに scripts/office/soffice.py で自動設定済み)