xlsx
npx skills add https://github.com/yamato-snow/skills --skill xlsx
Agent 安装分布
Skill 文档
åºåã®è¦ä»¶
ãã¹ã¦ã®Excelãã¡ã¤ã«
æ°å¼ã¨ã©ã¼ã¼ã
- ãã¹ã¦ã®Excelã¢ãã«ã¯ãæ°å¼ã¨ã©ã¼ï¼#REF!, #DIV/0!, #VALUE!, #N/A, #NAME?ï¼ãã¼ãã®ç¶æ ã§ç´åããå¿ è¦ãããã¾ã
æ¢åãã³ãã¬ã¼ãã®ä¿æï¼ãã³ãã¬ã¼ãæ´æ°æï¼
- ãã¡ã¤ã«å¤æ´æã¯æ¢åã®ãã©ã¼ããããã¹ã¿ã¤ã«ãè¦åã確èªãæ£ç¢ºã«ä¸è´ããã
- 確ç«ããããã¿ã¼ã³ãæã¤ãã¡ã¤ã«ã«æ¨æºåããããã©ã¼ããããå¼·å¶ããªã
- æ¢åã®ãã³ãã¬ã¼ãè¦åã¯å¸¸ã«ãããã®ã¬ã¤ãã©ã¤ã³ããåªå ããã
財åã¢ãã«
è²åãè¦æº
ã¦ã¼ã¶ã¼ã¾ãã¯æ¢åãã³ãã¬ã¼ãã§å¥éæå®ããã¦ããªãéã
æ¥çæ¨æºã®è²è¦å
- éè²ããã¹ã (RGB: 0,0,255): ãã¼ãã³ã¼ããããå ¥åå¤ãã·ããªãªç¨ã«ã¦ã¼ã¶ã¼ã夿´ããæ°å¤
- é»è²ããã¹ã (RGB: 0,0,0): ãã¹ã¦ã®æ°å¼ã¨è¨ç®
- ç·è²ããã¹ã (RGB: 0,128,0): åä¸ããã¯å ã®ä»ã®ã¯ã¼ã¯ã·ã¼ããããã«ãããªã³ã¯
- 赤è²ããã¹ã (RGB: 255,0,0): ä»ã®ãã¡ã¤ã«ã¸ã®å¤é¨ãªã³ã¯
- é»è²èæ¯ (RGB: 255,255,0): 注æãå¿ è¦ãªä¸»è¦åææ¡ä»¶ã¾ãã¯æ´æ°ãå¿ è¦ãªã»ã«
æ°å¤ãã©ã¼ãããè¦æº
å¿ é ãã©ã¼ãããã«ã¼ã«
- å¹´: ããã¹ãæååã¨ãã¦ãã©ã¼ãããï¼ä¾: “2024”ã”2,024″ã§ã¯ãªãï¼
- é貨: $#,##0å½¢å¼ã使ç¨; ãããã¼ã§å¿ ãåä½ãæå®ï¼”Revenue ($mm)”ï¼
- ã¼ã: æ°å¤ãã©ã¼ãããã§ãã¹ã¦ã®ã¼ãã”-“ã«ããããã¼ã»ã³ãã¼ã¸ãå«ãï¼ä¾: “$#,##0;($#,##0);-“ï¼
- ãã¼ã»ã³ãã¼ã¸: ããã©ã«ãã§0.0%å½¢å¼ï¼å°æ°ç¹ä»¥ä¸1æ¡ï¼
- åç: ããªã¥ã¨ã¼ã·ã§ã³åçï¼EV/EBITDA, P/Eï¼ã¯0.0xå½¢å¼
- è² ã®æ°å¤: ãã¤ãã¹è¨å·-123ã§ã¯ãªãæ¬å¼§(123)ã使ç¨
æ°å¼æ§ç¯ã«ã¼ã«
åææ¡ä»¶ã®é ç½®
- ãã¹ã¦ã®åææ¡ä»¶ï¼æé·çããã¼ã¸ã³ãåçãªã©ï¼ãå¥ã®åææ¡ä»¶ã»ã«ã«é ç½®
- æ°å¼å ã§ãã¼ãã³ã¼ããããå¤ã®ä»£ããã«ã»ã«åç §ã使ç¨
- ä¾: =B51.05ã®ä»£ããã«=B5(1+$B$6)ã使ç¨
æ°å¼ã¨ã©ã¼ã®é²æ¢
- ãã¹ã¦ã®ã»ã«åç §ãæ£ãããã¨ã確èª
- ç¯å²ã®ãªããã¤ã¯ã³ã¨ã©ã¼ããã§ãã¯
- ãã¹ã¦ã®äºæ¸¬æéã§ä¸è²«ããæ°å¼ã確ä¿
- ã¨ãã¸ã±ã¼ã¹ï¼ã¼ãå¤ãè² ã®æ°å¤ï¼ã§ãã¹ã
- æå³ããªã循ç°åç §ããªããã¨ã確èª
ãã¼ãã³ã¼ãã®ããã¥ã¡ã³ãè¦ä»¶
- ã»ã«ã«ã³ã¡ã³ãããããæ¨ªã«è¨è¼ï¼ãã¼ãã«ã®æ«å°¾ã®å ´åï¼ãå½¢å¼: “Source: [ã·ã¹ãã /ããã¥ã¡ã³ã], [æ¥ä»], [å ·ä½çãªåç §], [該å½ããå ´åã¯URL]”
- ä¾:
- “Source: Company 10-K, FY2024, Page 45, Revenue Note, [SEC EDGAR URL]”
- “Source: Company 10-Q, Q2 2025, Exhibit 99.1, [SEC EDGAR URL]”
- “Source: Bloomberg Terminal, 8/15/2025, AAPL US Equity”
- “Source: FactSet, 8/20/2025, Consensus Estimates Screen”
XLSXã®ä½æãç·¨éãåæ
æ¦è¦
ã¦ã¼ã¶ã¼ã¯.xlsxãã¡ã¤ã«ã®ä½æãç·¨éãã¾ãã¯å 容ã®åæãä¾é ¼ããå ´åãããã¾ããã¿ã¹ã¯ã«å¿ãã¦ç°ãªããã¼ã«ã¨ã¯ã¼ã¯ããã¼ãå©ç¨å¯è½ã§ãã
éè¦ãªè¦ä»¶
æ°å¼åè¨ç®ã«ã¯LibreOfficeãå¿
è¦: recalc.pyã¹ã¯ãªããã使ç¨ãã¦æ°å¼ã®å¤ãåè¨ç®ããããã«LibreOfficeãã¤ã³ã¹ãã¼ã«ããã¦ãããã¨ãåæã¨ãã¾ããã¹ã¯ãªããã¯ååå®è¡æã«èªåçã«LibreOfficeãè¨å®ãã¾ãã
ãã¼ã¿ã®èªã¿åãã¨åæ
pandasã«ãããã¼ã¿åæ
ãã¼ã¿åæãå¯è¦åãåºæ¬æä½ã«ã¯ãå¼·åãªãã¼ã¿æä½æ©è½ãæä¾ããpandasã使ç¨ãã¾ãï¼
import pandas as pd
# Excelãèªã¿è¾¼ã
df = pd.read_excel('file.xlsx') # ããã©ã«ã: æåã®ã·ã¼ã
all_sheets = pd.read_excel('file.xlsx', sheet_name=None) # ãã¹ã¦ã®ã·ã¼ããè¾æ¸ã¨ãã¦
# åæ
df.head() # ãã¼ã¿ã®ãã¬ãã¥ã¼
df.info() # ã«ã©ã æ
å ±
df.describe() # çµ±è¨æ
å ±
# Excelã«æ¸ãè¾¼ã
df.to_excel('output.xlsx', index=False)
Excelãã¡ã¤ã«ã®ã¯ã¼ã¯ããã¼
éè¦: ãã¼ãã³ã¼ããããå¤ã§ã¯ãªãæ°å¼ã使ç¨ãã
常ã«Pythonã§å¤ãè¨ç®ãã¦ãã¼ãã³ã¼ããã代ããã«Excelã®æ°å¼ã使ç¨ãã¦ãã ããã ããã«ãããã¹ãã¬ããã·ã¼ããåçã§æ´æ°å¯è½ãªç¶æ ãç¶æã§ãã¾ãã
â ééã – è¨ç®å¤ã®ãã¼ãã³ã¼ã
# æªãä¾: Pythonã§è¨ç®ãã¦çµæããã¼ãã³ã¼ã
total = df['Sales'].sum()
sheet['B10'] = total # 5000ããã¼ãã³ã¼ã
# æªãä¾: Pythonã§æé·çãè¨ç®
growth = (df.iloc[-1]['Revenue'] - df.iloc[0]['Revenue']) / df.iloc[0]['Revenue']
sheet['C5'] = growth # 0.15ããã¼ãã³ã¼ã
# æªãä¾: Pythonã§å¹³åãè¨ç®
avg = sum(values) / len(values)
sheet['D20'] = avg # 42.5ããã¼ãã³ã¼ã
â æ£ãã – Excelæ°å¼ã®ä½¿ç¨
# è¯ãä¾: Excelã«åè¨ãè¨ç®ããã
sheet['B10'] = '=SUM(B2:B9)'
# è¯ãä¾: æé·çãExcelæ°å¼ã¨ãã¦
sheet['C5'] = '=(C4-C2)/C2'
# è¯ãä¾: Excel颿°ã§å¹³åãè¨ç®
sheet['D20'] = '=AVERAGE(D2:D19)'
ããã¯ãã¹ã¦ã®è¨ç®ã«é©ç¨ããã¾ã – åè¨ããã¼ã»ã³ãã¼ã¸ãæ¯çãå·®åãªã©ãã¹ãã¬ããã·ã¼ãã¯ã½ã¼ã¹ãã¼ã¿ã夿´ãããã¨ãã«åè¨ç®ã§ããå¿ è¦ãããã¾ãã
ä¸è¬çãªã¯ã¼ã¯ããã¼
- ãã¼ã«ã鏿: ãã¼ã¿ã«ã¯pandasãæ°å¼/æ¸å¼è¨å®ã«ã¯openpyxl
- 使/èªã¿è¾¼ã¿: æ°è¦ã¯ã¼ã¯ããã¯ã使ãããæ¢åãã¡ã¤ã«ãèªã¿è¾¼ã
- 夿´: ãã¼ã¿ãæ°å¼ãæ¸å¼è¨å®ã追å /ç·¨é
- ä¿å: ãã¡ã¤ã«ã«æ¸ãè¾¼ã
- æ°å¼ãåè¨ç®ï¼æ°å¼ä½¿ç¨æã¯å¿
é ï¼: recalc.pyã¹ã¯ãªããã使ç¨
python recalc.py output.xlsx - ã¨ã©ã¼ã確èªãã¦ä¿®æ£:
- ã¹ã¯ãªããã¯ã¨ã©ã¼ã®è©³ç´°ãå«ãJSONãè¿ã
statusãerrors_foundã®å ´åãerror_summaryã§å ·ä½çãªã¨ã©ã¼ã¿ã¤ãã¨å ´æã確èª- ç¹å®ãããã¨ã©ã¼ãä¿®æ£ãã¦å度è¨ç®
- ä¿®æ£ãã¹ãä¸è¬çãªã¨ã©ã¼:
#REF!: ç¡å¹ãªã»ã«åç §#DIV/0!: ã¼ãé¤ç®#VALUE!: æ°å¼ã§ééã£ããã¼ã¿å#NAME?: èªèã§ããªãæ°å¼å
æ°è¦Excelãã¡ã¤ã«ã®ä½æ
# æ°å¼ã¨æ¸å¼è¨å®ã«openpyxlã使ç¨
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment
wb = Workbook()
sheet = wb.active
# ãã¼ã¿ã追å
sheet['A1'] = 'Hello'
sheet['B1'] = 'World'
sheet.append(['Row', 'of', 'data'])
# æ°å¼ã追å
sheet['B2'] = '=SUM(A1:A10)'
# æ¸å¼è¨å®
sheet['A1'].font = Font(bold=True, color='FF0000')
sheet['A1'].fill = PatternFill('solid', start_color='FFFF00')
sheet['A1'].alignment = Alignment(horizontal='center')
# åå¹
sheet.column_dimensions['A'].width = 20
wb.save('output.xlsx')
æ¢åExcelãã¡ã¤ã«ã®ç·¨é
# æ°å¼ã¨æ¸å¼è¨å®ãä¿æããããã«openpyxlã使ç¨
from openpyxl import load_workbook
# æ¢åãã¡ã¤ã«ãèªã¿è¾¼ã
wb = load_workbook('existing.xlsx')
sheet = wb.active # ã¾ãã¯ç¹å®ã®ã·ã¼ãã«wb['SheetName']
# è¤æ°ã®ã·ã¼ããæä½
for sheet_name in wb.sheetnames:
sheet = wb[sheet_name]
print(f"Sheet: {sheet_name}")
# ã»ã«ã夿´
sheet['A1'] = 'New Value'
sheet.insert_rows(2) # ä½ç½®2ã«è¡ãæ¿å
¥
sheet.delete_cols(3) # å3ãåé¤
# æ°ããã·ã¼ãã追å
new_sheet = wb.create_sheet('NewSheet')
new_sheet['A1'] = 'Data'
wb.save('modified.xlsx')
æ°å¼ã®åè¨ç®
openpyxlã§ä½æã¾ãã¯å¤æ´ãããExcelãã¡ã¤ã«ã«ã¯ãæ°å¼ãæååã¨ãã¦å«ã¾ãã¦ãã¾ãããè¨ç®ãããå¤ã¯å«ã¾ãã¦ãã¾ãããæä¾ãããrecalc.pyã¹ã¯ãªããã使ç¨ãã¦æ°å¼ãåè¨ç®ãã¦ãã ããï¼
python recalc.py <excel_file> [timeout_seconds]
ä¾ï¼
python recalc.py output.xlsx 30
ã¹ã¯ãªããã®æ©è½ï¼
- ååå®è¡æã«LibreOfficeãã¯ããèªåè¨å®
- ãã¹ã¦ã®ã·ã¼ãã®ãã¹ã¦ã®æ°å¼ãåè¨ç®
- ãã¹ã¦ã®ã»ã«ãã¹ãã£ã³ãã¦Excelã¨ã©ã¼ï¼#REF!, #DIV/0!ãªã©ï¼ãæ¤åº
- ã¨ã©ã¼ã®å ´æã¨æ°ã詳細ã«å«ãJSONãè¿ã
- Linuxã¨macOSã®ä¸¡æ¹ã§åä½
æ°å¼æ¤è¨¼ãã§ãã¯ãªã¹ã
æ°å¼ãæ£ããæ©è½ãããã¨ã確èªããããã®ã¯ã¤ãã¯ãã§ãã¯ï¼
å¿ é ã®æ¤è¨¼
- 2-3ã®ãµã³ãã«åç §ããã¹ã: å®å ¨ãªã¢ãã«ãæ§ç¯ããåã«æ£ããå¤ãåå¾ãã¦ãããã¨ã確èª
- åãããã³ã°: Excelåãä¸è´ãããã¨ã確èªï¼ä¾: å64 = BLãBKã§ã¯ãªãï¼
- è¡ãªãã»ãã: Excelã®è¡ã¯1ã¤ã³ããã¯ã¹ã§ãããã¨ãå¿ããã«ï¼DataFrameã®è¡5 = Excelã®è¡6ï¼
ä¸è¬çãªè½ã¨ãç©´
- NaNå¦ç:
pd.notna()ã§nullå¤ããã§ã㯠- å³ç«¯ã®å: FYãã¼ã¿ã¯50å以ä¸ã®å ´åãå¤ã
- è¤æ°ã®ä¸è´: æåã ãã§ãªããã¹ã¦ã®åºç¾ãæ¤ç´¢
- ã¼ãé¤ç®: æ°å¼ã§
/ã使ç¨ããåã«åæ¯ããã§ãã¯ï¼#DIV/0!ï¼ - ééã£ãåç §: ãã¹ã¦ã®ã»ã«åç §ãæå³ããã»ã«ãæãã¦ãããã¨ã確èªï¼#REF!ï¼
- ã·ã¼ãéåç §: ã·ã¼ãéããªã³ã¯ããéã¯æ£ããå½¢å¼ã使ç¨ï¼Sheet1!A1ï¼
æ°å¼ãã¹ãæ¦ç¥
- å°ããå§ãã: åºãé©ç¨ããåã«2-3ã»ã«ã§æ°å¼ããã¹ã
- ä¾åé¢ä¿ã確èª: æ°å¼ã§åç §ããããã¹ã¦ã®ã»ã«ãåå¨ãããã¨ããã§ãã¯
- ã¨ãã¸ã±ã¼ã¹ããã¹ã: ã¼ããè² ã®å¤ãé常ã«å¤§ããªå¤ãå«ãã
recalc.pyåºåã®è§£é
ã¹ã¯ãªããã¯ã¨ã©ã¼ã®è©³ç´°ãå«ãJSONãè¿ãã¾ãï¼
{
"status": "success", // ã¾ã㯠"errors_found"
"total_errors": 0, // ã¨ã©ã¼ã®ç·æ°
"total_formulas": 42, // ãã¡ã¤ã«å
ã®æ°å¼ã®æ°
"error_summary": { // ã¨ã©ã¼ãè¦ã¤ãã£ãå ´åã®ã¿åå¨
"#REF!": {
"count": 2,
"locations": ["Sheet1!B5", "Sheet1!C10"]
}
}
}
ãã¹ããã©ã¯ãã£ã¹
ã©ã¤ãã©ãªã®é¸æ
- pandas: ãã¼ã¿åæã䏿¬æä½ãã·ã³ãã«ãªãã¼ã¿ã¨ã¯ã¹ãã¼ãã«æé©
- openpyxl: è¤éãªæ¸å¼è¨å®ãæ°å¼ãExcelåºæã®æ©è½ã«æé©
openpyxlã§ã®ä½æ¥
- ã»ã«ã¤ã³ããã¯ã¹ã¯1ãã¼ã¹ï¼row=1, column=1ã¯ã»ã«A1ãæãï¼
- è¨ç®ãããå¤ãèªã¿åãã«ã¯
data_only=Trueã使ç¨:load_workbook('file.xlsx', data_only=True) - è¦å:
data_only=Trueã§éãã¦ä¿åããã¨ãæ°å¼ã¯å¤ã«ç½®ãæãããæ°¸ä¹ ã«å¤±ããã - 大ããªãã¡ã¤ã«ã®å ´å: èªã¿åãã«ã¯
read_only=Trueãæ¸ãè¾¼ã¿ã«ã¯write_only=Trueãä½¿ç¨ - æ°å¼ã¯ä¿æããããè©ä¾¡ãããªã – å¤ãæ´æ°ããã«ã¯recalc.pyã使ç¨
pandasã§ã®ä½æ¥
- æ¨è«ã®åé¡ãé¿ããããã«ãã¼ã¿åãæå®:
pd.read_excel('file.xlsx', dtype={'id': str}) - 大ããªãã¡ã¤ã«ã®å ´åãç¹å®ã®åãèªã¿åã:
pd.read_excel('file.xlsx', usecols=['A', 'C', 'E']) - æ¥ä»ãé©åã«å¦ç:
pd.read_excel('file.xlsx', parse_dates=['date_column'])
ã³ã¼ãã¹ã¿ã¤ã«ã¬ã¤ãã©ã¤ã³
éè¦: Excelæä½ç¨ã®Pythonã³ã¼ããçæããéï¼
- ä¸è¦ãªã³ã¡ã³ããªãã§æå°éã®ç°¡æ½ãªPythonã³ã¼ããæ¸ã
- åé·ãªå¤æ°åãéè¤ããæä½ãé¿ãã
- ä¸è¦ãªprintæãé¿ãã
Excelãã¡ã¤ã«èªä½ã«ã¤ãã¦ï¼
- è¤éãªæ°å¼ãéè¦ãªåææ¡ä»¶ãå«ãã»ã«ã«ã³ã¡ã³ãã追å
- ãã¼ãã³ã¼ããããå¤ã®ãã¼ã¿ã½ã¼ã¹ãææ¸å
- 主è¦ãªè¨ç®ã¨ã¢ãã«ã»ã¯ã·ã§ã³ã«ã¡ã¢ãå«ãã