XLSX 생성, 편집 및 분석
| 작업 | 접근 방식 |
|---|---|
| 생성 또는 수식/서식 포함 편집 | openpyxl — 아래 주의사항 참조 |
| 대량 데이터 입출력 | pandas (read_excel, to_excel) |
| 시트 빠른 확인 | markitdown file.xlsx — 시트당 ## SheetName 표시; .xlsm도 읽음. 셀 좌표는 제공되지 않으므로 이를 기반으로 편집을 계획하지 마십시오 |
| 모델 읽기 (수식 및 값) | load_workbook 2회 패스 — 아래 주의사항 참조 |
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, 그리고 오류 유형당 최대 100개 셀을 명명하는 error_summary (locations_truncated는 얼마나 많은 셀이 생략되었는지 알려줍니다 — 목록의 길이가 아닌 total_errors를 신뢰하십시오). 명명된 셀을 수정하고 다시 실행하십시오. status 대신 error 키가 있는 JSON은 재계산되지 않았음을 의미하며, 이 경우에만 종료 코드가 0이 아닙니다 — 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 주의사항
- 모델을 읽으려면 두 번 로드해야 합니다.
data_only=True는 수식이 없는 캐시된 값을 제공합니다. 기본값은 값이 없는 수식 문자열을 제공합니다. 한 번의 패스로 둘 다 얻을 수 없습니다. data_only=True는 저장 시 파괴적입니다. 해당 통합 문서에는 수식이 없으므로 저장 시 모든 수식이 리터럴로 영구적으로 대체됩니다.- 방금 openpyxl이 작성한 파일에
data_only=True를 사용하면 모든 곳에서None이 반환됩니다 — 먼저recalc.py를 실행하십시오. (결과가""인 수식도None으로 다시 읽힙니다.) - 병합된 셀: 왼쪽 상단 앵커에만 쓰십시오. 범위의 다른 모든 셀은
.value가 읽기 전용인MergedCell입니다. .xlsm은keep_vba=True를load_workbook에 전달하지 않으면 매크로가 손실됩니다.- 공백이 포함된 시트 이름은 시트 간 참조에서 따옴표로 묶어야 합니다:
='Assumptions Inputs'!$B$5. 따옴표 없이 사용하면#VALUE!로 평가됩니다.
재무 모델
사용자가 달리 명시하지 않거나 기존 파일이 다른 방식을 사용하지 않는 한.
색상: 하드코딩된 입력 및 시나리오 레버는 파란색 텍스트 (0,0,255) · 수식은 검정색 · 다른 시트에 대한 링크는 녹색 (0,128,0) · 다른 파일에 대한 링크는 빨간색 (255,0,0) · 주요 가정 및 사용자가 입력해야 하는 셀은 노란색 채우기 (255,255,0).
숫자: 통화 $#,##0, 헤더에 단위 명시 (수익 ($mm)) · 0은 -로 표시, 백분율 포함 ($#,##0;($#,##0);-) · 음수는 괄호 안에 · 백분율 0.0%, 분수로 저장 (0.15는 15.0%로 표시; 15를 저장하면 1500.0%로 표시) · 가치 평가 배수 0.0x · 연도는 텍스트로 ("2024", 절대 2,024 아님).
구조: 모든 가정은 자체 라벨이 지정된 셀에 배치하고, 이를 사용하는 수식에서 참조 (=B5*(1+$B$6), 절대 =B5*1.05 아님) · 모든 예측 기간에 걸쳐 수식 일관성 유지, 행 중간에 단독 편집된 셀이 가장 흔한 조용한 오류이므로 · 0이 될 수 있는 분모는 보호.
의존성
openpyxl, pandas, markitdown (pip, 사전 설치됨 — 임포트 실패 또는 명령 누락 시에만 설치) · LibreOffice (soffice, 샌드박스 환경에 맞게 scripts/office/soffice.py를 통해 자동 구성)
이 스킬은 Anthropic에서 생성 및 유지 관리합니다. 프런트매터 메타데이터를 제외하고 수정 없이 벤더에 포함되었습니다. 라이선스 조건은 LICENSE.txt를 참조하십시오.