[{"data":1,"prerenderedAt":455},["ShallowReactive",2],{"content-/ib-excel-format-template":3,"all-pages-for-dir":453,"og-image-/ib-excel-format-template":454},{"id":4,"title":5,"body":6,"category":433,"description":434,"extension":435,"meta":436,"navigation":242,"ogImage":437,"path":438,"project_name":439,"published":440,"publishedAt":441,"seo":442,"stem":443,"tags":444,"todo":451,"unpublished":440,"updatedAt":437,"__hash__":452},"pages/2026-04/2026-04-11/ib-excel-format-template.md","投資銀行スタイルのExcel書式設定をPythonで自動適用できるか検証した",{"type":7,"value":8,"toc":425},"minimark",[9,13,17,20,25,28,72,75,77,80,87,90,291,297,299,303,306,334,340,346,348,352,355,372,379,381,385,388,391,410,413,415,418,421],[10,11,5],"h1",{"id":12},"投資銀行スタイルのexcel書式設定をpythonで自動適用できるか検証した",[14,15,16],"p",{},"キャッシュフローコンテンツのExcel生成パイプラインでIBフォーマットの色分けを走らせてみて、ふと気づいた。この処理、対象ファイルを選ばないのでは。手元で検証した結果と、そこから浮かんだExcel演習シートの構想を書き残す。",[18,19],"hr",{},[21,22,24],"h2",{"id":23},"きっかけ-ibフォーマットの色分けルール","きっかけ: IBフォーマットの色分けルール",[14,26,27],{},"投資銀行スタイルの財務モデルでは、セルのフォント色で「データの出自」を一瞬で伝える:",[29,30,31,44],"table",{},[32,33,34],"thead",{},[35,36,37,41],"tr",{},[38,39,40],"th",{},"フォント色",[38,42,43],{},"意味",[45,46,47,56,64],"tbody",{},[35,48,49,53],{},[50,51,52],"td",{},"黒",[50,54,55],{},"同一シート内で完結する計算式",[35,57,58,61],{},[50,59,60],{},"緑",[50,62,63],{},"他シートから参照している数式",[35,65,66,69],{},[50,67,68],{},"青",[50,70,71],{},"ハードコード値（直接入力された数値）",[14,73,74],{},"CFWSパイプラインでこの色分けを自動適用していたが、「これ、既存のExcelファイルにも後付けで塗れないか？」という疑問が浮かんだ。",[18,76],{},[21,78,79],{"id":79},"openpyxlで安全にフォント色だけ変える",[14,81,82,83],{},"結論: ",[84,85,86],"strong",{},"セルの値・数式・書式の大部分を壊さずに、フォント色だけ差し替えられる。",[14,88,89],{},"判定ロジックの骨格はこれだけ:",[91,92,97],"pre",{"className":93,"code":94,"language":95,"meta":96,"style":96},"language-python shiki shiki-themes vitesse-light vitesse-light","if '!' in cell.value:\n    color = '008000'   # 緑: 他シート参照\nelif isinstance(cell.value, (int, float)):\n    color = '0000FF'   # 青: ハードコード数値\nelse:\n    color = '000000'   # 黒: シート内計算\n\ncell.font = cell.font.copy(color=Color(rgb=color))\n","python","",[98,99,100,138,158,195,212,220,237,244],"code",{"__ignoreMap":96},[101,102,105,109,113,117,120,124,128,132,135],"span",{"class":103,"line":104},"line",1,[101,106,108],{"class":107},"sHkkW","if",[101,110,112],{"class":111},"sMJiu"," '",[101,114,116],{"class":115},"sdGka","!",[101,118,119],{"class":111},"'",[101,121,123],{"class":122},"stQ0i"," in",[101,125,127],{"class":126},"sG7-3"," cell",[101,129,131],{"class":130},"shFtX",".",[101,133,134],{"class":126},"value",[101,136,137],{"class":130},":\n",[101,139,141,144,147,149,152,154],{"class":103,"line":140},2,[101,142,143],{"class":126},"    color ",[101,145,146],{"class":130},"=",[101,148,112],{"class":111},[101,150,151],{"class":115},"008000",[101,153,119],{"class":111},[101,155,157],{"class":156},"sxvE3","   # 緑: 他シート参照\n",[101,159,161,164,168,171,174,176,178,181,184,187,189,192],{"class":103,"line":160},3,[101,162,163],{"class":107},"elif",[101,165,167],{"class":166},"sz8Xr"," isinstance",[101,169,170],{"class":130},"(",[101,172,173],{"class":126},"cell",[101,175,131],{"class":130},[101,177,134],{"class":126},[101,179,180],{"class":130},",",[101,182,183],{"class":130}," (",[101,185,186],{"class":166},"int",[101,188,180],{"class":130},[101,190,191],{"class":166}," float",[101,193,194],{"class":130},")):\n",[101,196,198,200,202,204,207,209],{"class":103,"line":197},4,[101,199,143],{"class":126},[101,201,146],{"class":130},[101,203,112],{"class":111},[101,205,206],{"class":115},"0000FF",[101,208,119],{"class":111},[101,210,211],{"class":156},"   # 青: ハードコード数値\n",[101,213,215,218],{"class":103,"line":214},5,[101,216,217],{"class":107},"else",[101,219,137],{"class":130},[101,221,223,225,227,229,232,234],{"class":103,"line":222},6,[101,224,143],{"class":126},[101,226,146],{"class":130},[101,228,112],{"class":111},[101,230,231],{"class":115},"000000",[101,233,119],{"class":111},[101,235,236],{"class":156},"   # 黒: シート内計算\n",[101,238,240],{"class":103,"line":239},7,[101,241,243],{"emptyLinePlaceholder":242},true,"\n",[101,245,247,249,251,254,256,258,260,263,265,268,270,274,276,279,281,284,286,288],{"class":103,"line":246},8,[101,248,173],{"class":126},[101,250,131],{"class":130},[101,252,253],{"class":126},"font ",[101,255,146],{"class":130},[101,257,127],{"class":126},[101,259,131],{"class":130},[101,261,262],{"class":126},"font",[101,264,131],{"class":130},[101,266,267],{"class":126},"copy",[101,269,170],{"class":130},[101,271,273],{"class":272},"s4oTP","color",[101,275,146],{"class":130},[101,277,278],{"class":126},"Color",[101,280,170],{"class":130},[101,282,283],{"class":272},"rgb",[101,285,146],{"class":130},[101,287,273],{"class":126},[101,289,290],{"class":130},"))\n",[14,292,293,296],{},[98,294,295],{},"cell.font.copy()"," で既存のフォント属性（サイズ、太字など）を保持したまま色だけ書き換える。数式文字列もリンクも値もそのまま残る。",[18,298],{},[21,300,302],{"id":301},"ibモデルの設計思想が自動色分けと噛み合う理由","IBモデルの設計思想が自動色分けと噛み合う理由",[14,304,305],{},"投資銀行のモデルは「セルをクリックすれば参照先が見える」という透明性を最優先する。だから以下のような機能を使わない:",[307,308,309,316,322,328],"ul",{},[310,311,312,315],"li",{},[84,313,314],{},"INDIRECT関数"," -- 参照先が文字列に隠れて追跡できない",[310,317,318,321],{},[84,319,320],{},"名前付き範囲"," -- 定義を開かないと参照先がわからない",[310,323,324,327],{},[84,325,326],{},"パワーピボット / 外部データ接続"," -- セル上に数式が残らない",[310,329,330,333],{},[84,331,332],{},"マクロ（VBA）"," -- コードを開かないと処理が見えない",[14,335,336,337,339],{},"つまり数式中の ",[98,338,116],{}," の有無だけで他シート参照を判定できるという前提が、IBモデルではほぼ成立する。判定ロジックが単純でも誤判定が起きにくい。",[14,341,342,343,345],{},"逆に言えば、INDIRECT経由で他シートを参照していたり、名前付き範囲で他シートのセルを指している場合は ",[98,344,116],{}," が数式文字列に現れないため黒に誤判定される。ただしIBの世界ではそもそもそういう設計をしない。",[18,347],{},[21,349,351],{"id":350},"openpyxlの開いて保存するだけで壊れるもの","openpyxlの「開いて保存するだけで壊れるもの」",[14,353,354],{},"フォント色の変更自体は安全でも、openpyxlでファイルを開いて保存する行為自体に落とし穴がある:",[307,356,357,360,363,366,369],{},[310,358,359],{},"ピボットテーブル",[310,361,362],{},"スパークライン",[310,364,365],{},"Power Query接続",[310,367,368],{},"一部の条件付き書式",[310,370,371],{},"配列数式（CSE）の扱いが不完全",[14,373,374,375,378],{},"自分たちのパイプラインで生成したExcelにはこれらが含まれないので問題ないが、他人が作った複雑なExcelに適用するなら",[84,376,377],{},"バックアップ必須","。",[18,380],{},[21,382,384],{"id":383},"構想-ibフォーマット演習シート","構想: IBフォーマット演習シート",[14,386,387],{},"この検証の延長で、フォント色・罫線・セルの色設定をショートカットで練習できるExcel演習シートを思いついた。",[14,389,390],{},"想定する中身:",[307,392,393,396,407],{},[310,394,395],{},"意図的に色がバラバラなセルを並べて、IBルールに沿って手動で塗り直す演習",[310,397,398,399,402,403,406],{},"ショートカットキーの一覧シート（",[98,400,401],{},"Alt + H + FC"," でフォント色、",[98,404,405],{},"Alt + H + H"," でセルの色など）",[310,408,409],{},"正解シートを別タブに用意し、マクロなしで自己採点できる構成",[14,411,412],{},"IBフォーマットのルール自体は単純だが、手が覚えるまでは意外に時間がかかる。Excelを毎日触る人向けの反復練習教材として需要がありそう。",[18,414],{},[21,416,417],{"id":417},"振り返り",[14,419,420],{},"CFWSパイプラインの色分け処理を眺めているうちに、「これは汎用ツールになる」と手が勝手にREPLを開いていた。IBモデルが「直接参照しか使わない」という制約を自らに課しているからこそ、機械的な判定が破綻しない。制約が自動化を可能にする、という構図が面白い。",[422,423,424],"style",{},"html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html pre.shiki code .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .sG7-3, html code.shiki .sG7-3{--shiki-default:#393A34;--shiki-dark:#393A34}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html pre.shiki code .sz8Xr, html code.shiki .sz8Xr{--shiki-default:#998418;--shiki-dark:#998418}html pre.shiki code .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":96,"searchDepth":140,"depth":140,"links":426},[427,428,429,430,431,432],{"id":23,"depth":140,"text":24},{"id":79,"depth":140,"text":79},{"id":301,"depth":140,"text":302},{"id":350,"depth":140,"text":351},{"id":383,"depth":140,"text":384},{"id":417,"depth":140,"text":417},"dev","openpyxlでフォント色のみを変更する処理がセルの値・数式・書式を壊さないことを確認。IBモデルの設計思想が自動色分けと相性が良い理由と、Excel演習シートの構想","md",{},null,"/ib-excel-format-template","eurekapu-nuxt4",false,"2026-04-11T00:00:00.000Z",{"title":5,"description":434},"2026-04/2026-04-11/ib-excel-format-template",[445,446,447,448,449,450],"投資銀行","Excel","openpyxl","財務モデル","書式設定","Python","memo","GAqaNkbz26cxOigEAnm4fF0Khtz2dpYEDGRmyK_qnY8",[],"https://log.eurekapu.com/og/blog/ib-excel-format-template.png?v=2026-04-11T00%3A00%3A00.000Z&title=%E6%8A%95%E8%B3%87%E9%8A%80%E8%A1%8C%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%81%AEExcel%E6%9B%B8%E5%BC%8F%E8%A8%AD%E5%AE%9A%E3%82%92Python%E3%81%A7%E8%87%AA%E5%8B%95%E9%81%A9%E7%94%A8%E3%81%A7%E3%81%8D%E3%82%8B%E3%81%8B%E6%A4%9C%E8%A8%BC%E3%81%97%E3%81%9F&author=Kei%20Komatsu&sig=35755b48de6d42f9",1782528825569]