XLSX 建立、編輯與分析
| 任務 | 方法 |
|---|---|
| 建立或編輯(含公式/格式) | openpyxl — 請參閱下方注意事項 |
| 大量資料的匯入或匯出 | pandas (read_excel, to_excel) |
| 快速檢視工作表 | markitdown file.xlsx — 每個工作表顯示為 ## SheetName;也支援讀取 .xlsm。不包含儲存格座標,因此請勿據以規劃編輯 |
| 讀取模型(公式與數值) | 兩次 load_workbook 傳遞 — 請參閱注意事項 |
openpyxl、pandas和markitdown已預先安裝 — 請勿先執行uv pip install;直接撰寫腳本並匯入。僅在匯入失敗(或缺少markitdown指令)時:使用uv pip install安裝缺少的套件。
以下腳本路徑是相對於此技能目錄。
每個輸出檔案的要求
- 專業字型(Arial、Times New Roman)貫穿整個檔案,除非使用者另有指示。
- 零公式錯誤。 當
recalc.py回報errors_found時,絕不可交付。若你認為錯誤在你接手前就已存在,請證明它:使用data_only=True載入原始檔案並檢查該儲存格。你引入的錯誤與你繼承的錯誤看起來無異。 - 使用公式,絕不使用硬編碼的結果。 撰寫
sheet['B10'] = '=SUM(B2:B9)',而非 Python 計算出的總和。當輸入變更時,工作表必須能夠重新計算。 - 嚴格遵循使用者的規格。 確切的頁籤名稱、確切的欄位標題,以及他們指定的公式。一個計算出不同結果的重新設計,無論多麼優雅,都是失敗的。
- 在讀者看得見的地方記錄每個假設和硬編碼的數字 — 可以是儲存格註解,或表格結尾處的相鄰儲存格。當有真實來源時請引用它(
來源:公司 10-K, FY2024, 第45頁,收入附註, [SEC EDGAR URL]);若數字來自使用者,請直接說明。 - 你為他人填寫而建立的活頁簿需要一個簡短的圖例,指明要編輯的儲存格,以及一個包含真實數字的範例列,顯示預期的格式。切勿將此類列加入你被要求編輯的檔案中。
- 編輯現有檔案:完全遵循其慣例。 它們會覆蓋此處的所有準則。首先找出其指定的輸入儲存格 — 它們通常以獨特字型顏色、填滿或陰影標記 — 僅在該處寫入,並保持所有現有公式不變。
重新計算(當檔案包含公式時為強制步驟)
openpyxl 將公式寫入為字串,且沒有快取值。在你重新計算之前,任何讀取快取值的操作 — pandas、load_workbook(data_only=True) 以及大多數預覽器 — 都會將每個公式儲存格讀回為 None。
python scripts/recalc.py output.xlsx [timeout_seconds] # 預設 30
LibreOffice 會計算每個公式,檔案會原地覆寫,並回傳 JSON:包含 status (success | errors_found)、total_formulas、total_errors,以及一個 error_summary,針對每種錯誤類型列出最多 100 個儲存格(locations_truncated 表示省略了多少個 — 請相信 total_errors,而非清單的長度)。修正它所命名的錯誤後再次執行。當 JSON 包含 error 鍵而非 status 時,表示未進行任何重新計算,且只有這種情況會以非零狀態結束 — errors_found 會以零狀態結束,因此切勿將乾淨的結束視為乾淨的活頁簿。
一次成功的重新計算證明你的公式可被評估,但並非正確。 一個差一格的範圍或一個指向錯誤列的參照,會產生一個乾淨、無誤的檔案,但其中包含錯誤的數字。在建立整個表格前,先撰寫 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— 這些不需要前綴。 - 以下六個 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 注意事項
- 讀取模型需要兩次載入。
data_only=True會產生快取值,但公式會消失;預設模式會產生公式字串,但沒有數值。一次傳遞無法同時取得兩者。 - 如果儲存,
data_only=True具有破壞性。 該活頁簿不再有公式,因此儲存會用文字永久取代每個公式。 - 對 openpyxl 剛寫入的檔案使用
data_only=True會到處回傳None— 請先執行recalc.py。(一個結果為""的公式也會讀回為None。) - 合併儲存格:僅寫入左上角錨點。 範圍內的其他每個儲存格都是
MergedCell,其.value是唯讀的。 - 除非你將
keep_vba=True傳遞給load_workbook,否則.xlsm會遺失其巨集。 - 包含空格的工作表名稱必須用引號括起來,用於跨工作表參照:
='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 為沙盒環境自動設定)
此技能由 Anthropic 建立與維護。除了前端元資料外,此處未經修改直接引用;條款請參閱 LICENSE.txt。