Skip to content

Instantly share code, notes, and snippets.

@ngs
Last active September 26, 2025 13:31
Show Gist options
  • Save ngs/5029f1d12b56124e6b3430c6318cac53 to your computer and use it in GitHub Desktop.
Save ngs/5029f1d12b56124e6b3430c6318cac53 to your computer and use it in GitHub Desktop.

1. 月次集計シート - SUMIFS/COUNTIFS式 (行129, 132, 138, 141):

=COUNTIFS('売上データ'!B:B,">="&DATE(2024,{month},1),'売上データ'!B:B,"<"&DATE(2024,{month+1 if month < 12 else 1},1))
=SUMIFS('計算シート'!F:F,'売上データ'!B:B,">="&DATE(2024,{month},1),'売上データ'!B:B,"<"&DATE(2024,{month+1 if month < 12 else 1},1))

複数条件での集計、日付関数、シート間参照を組み合わせた複雑な式。

2. カテゴリ分析シート - ABC分類式 (行221):

=IF(C{idx}/SUM(C$2:C$4)>0.5,"A",IF(C{idx}/SUM(C$2:C$4)>0.2,"B","C"))

ネストされたIF文と相対/絶対参照の組み合わせ。

  1. ダッシュボード - 最高業績地域検索式 (行259):
=INDEX('地域別分析'!A:A,MATCH(MAX('地域別分析'!C:C),'地域別分析'!C:C,0))

INDEX / MATCH 関数と MAX 関数を組み合わせた高度な検索式。

4. 営業担当分析シート - ボーナス係数式 (行366):

=IF(D{idx}>1,1.5,IF(D{idx}>0.8,1.2,IF(D{idx}>0.6,1,0.8)))

3重にネストされた IF 文による複雑な条件分岐。

5. 予測モデルシート - 季節調整式 (行472):

=C{row}*(1+SIN(2*PI()*{(month-1)%12}/12)*0.15)

三角関数を使った季節性調整の数式。

これらの中で最も複雑なのは 月次集計の SUMIFS / MAXIFS / MINIFS 式 で、複数シート参照、複数条件、DATE関数の組み合わせが含まれています。

import openpyxl
from openpyxl import Workbook
from openpyxl.styles import PatternFill, Font, Alignment, Border, Side
from openpyxl.formatting.rule import ColorScaleRule, DataBarRule, IconSetRule
from openpyxl.chart import BarChart, LineChart, PieChart, ScatterChart, Reference
from openpyxl.utils import get_column_letter
import random
from datetime import datetime, timedelta
import math
def create_complex_workbook():
wb = Workbook()
# シート1: 売上データ (基本データ)
ws_sales = wb.active
ws_sales.title = "売上データ"
# ヘッダー設定
headers = ["ID", "日付", "製品コード", "製品名", "カテゴリ", "単価", "数量", "割引率", "税率", "地域", "営業担当"]
for col, header in enumerate(headers, 1):
ws_sales.cell(row=1, column=col, value=header)
ws_sales.cell(row=1, column=col).font = Font(bold=True)
ws_sales.cell(row=1, column=col).fill = PatternFill(start_color="366092", end_color="366092", fill_type="solid")
ws_sales.cell(row=1, column=col).font = Font(color="FFFFFF", bold=True)
# データ生成
products = [
("P001", "ノートPC Pro", "電子機器", 150000),
("P002", "ワイヤレスマウス", "周辺機器", 3500),
("P003", "USBメモリ 64GB", "ストレージ", 2800),
("P004", "モニター 27inch", "電子機器", 45000),
("P005", "キーボード メカニカル", "周辺機器", 12000),
("P006", "外付けHDD 2TB", "ストレージ", 8900),
("P007", "Webカメラ HD", "周辺機器", 5600),
("P008", "タブレット 10inch", "電子機器", 68000)
]
regions = ["東京", "大阪", "名古屋", "福岡", "札幌"]
sales_persons = ["田中", "佐藤", "鈴木", "高橋", "伊藤"]
start_date = datetime(2024, 1, 1)
for row in range(2, 202): # 200行のデータ
ws_sales.cell(row=row, column=1, value=row-1) # ID
ws_sales.cell(row=row, column=2, value=start_date + timedelta(days=random.randint(0, 364))) # 日付
product = random.choice(products)
ws_sales.cell(row=row, column=3, value=product[0]) # 製品コード
ws_sales.cell(row=row, column=4, value=product[1]) # 製品名
ws_sales.cell(row=row, column=5, value=product[2]) # カテゴリ
ws_sales.cell(row=row, column=6, value=product[3]) # 単価
ws_sales.cell(row=row, column=7, value=random.randint(1, 20)) # 数量
ws_sales.cell(row=row, column=8, value=random.choice([0, 0.05, 0.1, 0.15, 0.2])) # 割引率
ws_sales.cell(row=row, column=9, value=0.1) # 税率
ws_sales.cell(row=row, column=10, value=random.choice(regions)) # 地域
ws_sales.cell(row=row, column=11, value=random.choice(sales_persons)) # 営業担当
# シート2: 計算シート (複雑な数式)
ws_calc = wb.create_sheet("計算シート")
# ヘッダー
calc_headers = ["ID", "売上高", "割引額", "税抜金額", "消費税", "純売上", "粗利益", "粗利益率", "累積売上", "移動平均", "標準偏差", "Zスコア"]
for col, header in enumerate(calc_headers, 1):
ws_calc.cell(row=1, column=col, value=header)
ws_calc.cell(row=1, column=col).font = Font(bold=True)
ws_calc.cell(row=1, column=col).fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
ws_calc.cell(row=1, column=col).font = Font(color="FFFFFF", bold=True)
# 複雑な数式の設定
for row in range(2, 202):
# ID参照
ws_calc.cell(row=row, column=1, value=f"='売上データ'!A{row}")
# 売上高 = 単価 × 数量
ws_calc.cell(row=row, column=2, value=f"='売上データ'!F{row}*'売上データ'!G{row}")
# 割引額 = 売上高 × 割引率
ws_calc.cell(row=row, column=3, value=f"=B{row}*'売上データ'!H{row}")
# 税抜金額 = 売上高 - 割引額
ws_calc.cell(row=row, column=4, value=f"=B{row}-C{row}")
# 消費税 = 税抜金額 × 税率
ws_calc.cell(row=row, column=5, value=f"=D{row}*'売上データ'!I{row}")
# 純売上 = 税抜金額 + 消費税
ws_calc.cell(row=row, column=6, value=f"=D{row}+E{row}")
# 粗利益 (仮定: 原価率60%)
ws_calc.cell(row=row, column=7, value=f"=D{row}*0.4")
# 粗利益率
ws_calc.cell(row=row, column=8, value=f"=IF(D{row}=0,0,G{row}/D{row})")
# 累積売上
if row == 2:
ws_calc.cell(row=row, column=9, value=f"=F{row}")
else:
ws_calc.cell(row=row, column=9, value=f"=I{row-1}+F{row}")
# 移動平均 (10期)
if row >= 11:
ws_calc.cell(row=row, column=10, value=f"=AVERAGE(F{row-9}:F{row})")
else:
ws_calc.cell(row=row, column=10, value=f"=AVERAGE(F2:F{row})")
# 標準偏差 (全期間)
ws_calc.cell(row=row, column=11, value=f"=STDEV(F$2:F{row})")
# Zスコア
ws_calc.cell(row=row, column=12, value=f"=IF(K{row}=0,0,(F{row}-AVERAGE(F$2:F$201))/K{row})")
# シート3: 月次集計
ws_monthly = wb.create_sheet("月次集計")
# ヘッダー
monthly_headers = ["月", "売上件数", "総売上", "平均売上", "最大売上", "最小売上", "前月比", "前年同月比", "目標達成率"]
for col, header in enumerate(monthly_headers, 1):
ws_monthly.cell(row=1, column=col, value=header)
ws_monthly.cell(row=1, column=col).font = Font(bold=True)
ws_monthly.cell(row=1, column=col).fill = PatternFill(start_color="70AD47", end_color="70AD47", fill_type="solid")
ws_monthly.cell(row=1, column=col).font = Font(color="FFFFFF", bold=True)
# 月次データの設定
for month in range(1, 13):
row = month + 1
ws_monthly.cell(row=row, column=1, value=f"2024/{month:02d}")
# 売上件数 (COUNTIFS)
ws_monthly.cell(row=row, column=2, value=f"=COUNTIFS('売上データ'!B:B,\">=\"&DATE(2024,{month},1),'売上データ'!B:B,\"<\"&DATE(2024,{month+1 if month < 12 else 1},1))")
# 総売上 (SUMIFS)
ws_monthly.cell(row=row, column=3, value=f"=SUMIFS('計算シート'!F:F,'売上データ'!B:B,\">=\"&DATE(2024,{month},1),'売上データ'!B:B,\"<\"&DATE(2024,{month+1 if month < 12 else 1},1))")
# 平均売上
ws_monthly.cell(row=row, column=4, value=f"=IF(B{row}=0,0,C{row}/B{row})")
# 最大売上
ws_monthly.cell(row=row, column=5, value=f"=MAXIFS('計算シート'!F:F,'売上データ'!B:B,\">=\"&DATE(2024,{month},1),'売上データ'!B:B,\"<\"&DATE(2024,{month+1 if month < 12 else 1},1))")
# 最小売上
ws_monthly.cell(row=row, column=6, value=f"=MINIFS('計算シート'!F:F,'売上データ'!B:B,\">=\"&DATE(2024,{month},1),'売上データ'!B:B,\"<\"&DATE(2024,{month+1 if month < 12 else 1},1))")
# 前月比
if row > 2:
ws_monthly.cell(row=row, column=7, value=f"=IF(C{row-1}=0,0,(C{row}-C{row-1})/C{row-1})")
else:
ws_monthly.cell(row=row, column=7, value=0)
# 前年同月比 (仮想)
ws_monthly.cell(row=row, column=8, value=f"=RANDBETWEEN(90,120)/100-1")
# 目標達成率 (目標を1000万と仮定)
ws_monthly.cell(row=row, column=9, value=f"=C{row}/10000000")
# シート4: 地域別分析
ws_region = wb.create_sheet("地域別分析")
# ヘッダー
region_headers = ["地域", "売上件数", "総売上", "市場シェア", "成長率", "利益率", "ROI", "顧客単価", "リピート率"]
for col, header in enumerate(region_headers, 1):
ws_region.cell(row=1, column=col, value=header)
ws_region.cell(row=1, column=col).font = Font(bold=True)
ws_region.cell(row=1, column=col).fill = PatternFill(start_color="FFC000", end_color="FFC000", fill_type="solid")
# 地域データ
for idx, region in enumerate(regions, 2):
ws_region.cell(row=idx, column=1, value=region)
# 売上件数
ws_region.cell(row=idx, column=2, value=f"=COUNTIF('売上データ'!J:J,A{idx})")
# 総売上
ws_region.cell(row=idx, column=3, value=f"=SUMIF('売上データ'!J:J,A{idx},'計算シート'!F:F)")
# 市場シェア
ws_region.cell(row=idx, column=4, value=f"=C{idx}/SUM(C$2:C$6)")
# 成長率 (ランダム)
ws_region.cell(row=idx, column=5, value=f"=RANDBETWEEN(5,25)/100")
# 利益率
ws_region.cell(row=idx, column=6, value=f"=SUMIF('売上データ'!J:J,A{idx},'計算シート'!G:G)/C{idx}")
# ROI
ws_region.cell(row=idx, column=7, value=f"=F{idx}*1.5")
# 顧客単価
ws_region.cell(row=idx, column=8, value=f"=C{idx}/B{idx}")
# リピート率
ws_region.cell(row=idx, column=9, value=f"=RANDBETWEEN(60,90)/100")
# シート5: 製品カテゴリ分析
ws_category = wb.create_sheet("カテゴリ分析")
# ヘッダー
cat_headers = ["カテゴリ", "売上数量", "売上高", "平均単価", "在庫回転率", "ABC分類", "需要予測", "季節指数"]
for col, header in enumerate(cat_headers, 1):
ws_category.cell(row=1, column=col, value=header)
ws_category.cell(row=1, column=col).font = Font(bold=True)
ws_category.cell(row=1, column=col).fill = PatternFill(start_color="7030A0", end_color="7030A0", fill_type="solid")
ws_category.cell(row=1, column=col).font = Font(color="FFFFFF", bold=True)
categories = ["電子機器", "周辺機器", "ストレージ"]
for idx, category in enumerate(categories, 2):
ws_category.cell(row=idx, column=1, value=category)
# 売上数量
ws_category.cell(row=idx, column=2, value=f"=SUMIF('売上データ'!E:E,A{idx},'売上データ'!G:G)")
# 売上高
ws_category.cell(row=idx, column=3, value=f"=SUMIF('売上データ'!E:E,A{idx},'計算シート'!F:F)")
# 平均単価
ws_category.cell(row=idx, column=4, value=f"=C{idx}/B{idx}")
# 在庫回転率
ws_category.cell(row=idx, column=5, value=f"=12*B{idx}/(B{idx}*0.15)")
# ABC分類
ws_category.cell(row=idx, column=6, value=f"=IF(C{idx}/SUM(C$2:C$4)>0.5,\"A\",IF(C{idx}/SUM(C$2:C$4)>0.2,\"B\",\"C\"))")
# 需要予測 (移動平均ベース)
ws_category.cell(row=idx, column=7, value=f"=C{idx}*1.1")
# 季節指数
ws_category.cell(row=idx, column=8, value=f"=1+SIN(PI()*{idx}/6)*0.2")
# シート6: ダッシュボード
ws_dashboard = wb.create_sheet("ダッシュボード")
# タイトル
ws_dashboard.cell(row=1, column=1, value="営業ダッシュボード 2024")
ws_dashboard.cell(row=1, column=1).font = Font(size=20, bold=True)
ws_dashboard.merge_cells("A1:H1")
# KPI サマリー
kpi_row = 3
ws_dashboard.cell(row=kpi_row, column=1, value="KPI指標")
ws_dashboard.cell(row=kpi_row, column=1).font = Font(bold=True, size=14)
# 総売上
ws_dashboard.cell(row=kpi_row+1, column=1, value="総売上高:")
ws_dashboard.cell(row=kpi_row+1, column=2, value="=SUM('計算シート'!F:F)")
ws_dashboard.cell(row=kpi_row+1, column=2).number_format = "#,##0"
# 平均売上
ws_dashboard.cell(row=kpi_row+2, column=1, value="平均売上高:")
ws_dashboard.cell(row=kpi_row+2, column=2, value="=AVERAGE('計算シート'!F:F)")
ws_dashboard.cell(row=kpi_row+2, column=2).number_format = "#,##0"
# 売上成長率
ws_dashboard.cell(row=kpi_row+3, column=1, value="売上成長率:")
ws_dashboard.cell(row=kpi_row+3, column=2, value="=('月次集計'!C13-'月次集計'!C2)/'月次集計'!C2")
ws_dashboard.cell(row=kpi_row+3, column=2).number_format = "0.0%"
# 最高業績地域
ws_dashboard.cell(row=kpi_row+4, column=1, value="最高業績地域:")
ws_dashboard.cell(row=kpi_row+4, column=2, value="=INDEX('地域別分析'!A:A,MATCH(MAX('地域別分析'!C:C),'地域別分析'!C:C,0))")
# 最も売れた製品
ws_dashboard.cell(row=kpi_row+5, column=1, value="ベストセラー:")
ws_dashboard.cell(row=kpi_row+5, column=2, value="=INDEX('売上データ'!D:D,MODE('売上データ'!A:A)+1)")
# 平均粗利益率
ws_dashboard.cell(row=kpi_row+6, column=1, value="平均粗利益率:")
ws_dashboard.cell(row=kpi_row+6, column=2, value="=AVERAGE('計算シート'!H:H)")
ws_dashboard.cell(row=kpi_row+6, column=2).number_format = "0.0%"
# トレンド分析
trend_row = kpi_row + 8
ws_dashboard.cell(row=trend_row, column=1, value="トレンド分析")
ws_dashboard.cell(row=trend_row, column=1).font = Font(bold=True, size=14)
# 売上トレンド
ws_dashboard.cell(row=trend_row+1, column=1, value="売上トレンド:")
ws_dashboard.cell(row=trend_row+1, column=2, value="=IF(SLOPE('月次集計'!C2:C13,ROW('月次集計'!C2:C13))>0,\"上昇傾向\",\"下降傾向\")")
# 季節性
ws_dashboard.cell(row=trend_row+2, column=1, value="季節性指数:")
ws_dashboard.cell(row=trend_row+2, column=2, value="=STDEV('月次集計'!C2:C13)/AVERAGE('月次集計'!C2:C13)")
ws_dashboard.cell(row=trend_row+2, column=2).number_format = "0.00"
# 予測精度
ws_dashboard.cell(row=trend_row+3, column=1, value="予測精度:")
ws_dashboard.cell(row=trend_row+3, column=2, value="=1-ABS(AVERAGE('月次集計'!I2:I13)-1)")
ws_dashboard.cell(row=trend_row+3, column=2).number_format = "0.0%"
# 高度な分析セクション
analysis_row = trend_row + 5
ws_dashboard.cell(row=analysis_row, column=1, value="高度な分析")
ws_dashboard.cell(row=analysis_row, column=1).font = Font(bold=True, size=14)
# 相関分析
ws_dashboard.cell(row=analysis_row+1, column=1, value="価格-数量相関:")
ws_dashboard.cell(row=analysis_row+1, column=2, value="=CORREL('売上データ'!F:F,'売上データ'!G:G)")
ws_dashboard.cell(row=analysis_row+1, column=2).number_format = "0.000"
# 分散分析
ws_dashboard.cell(row=analysis_row+2, column=1, value="売上分散:")
ws_dashboard.cell(row=analysis_row+2, column=2, value="=VAR('計算シート'!F:F)")
ws_dashboard.cell(row=analysis_row+2, column=2).number_format = "#,##0"
# 四分位数
ws_dashboard.cell(row=analysis_row+3, column=1, value="第1四分位:")
ws_dashboard.cell(row=analysis_row+3, column=2, value="=QUARTILE('計算シート'!F:F,1)")
ws_dashboard.cell(row=analysis_row+3, column=2).number_format = "#,##0"
ws_dashboard.cell(row=analysis_row+4, column=1, value="中央値:")
ws_dashboard.cell(row=analysis_row+4, column=2, value="=MEDIAN('計算シート'!F:F)")
ws_dashboard.cell(row=analysis_row+4, column=2).number_format = "#,##0"
ws_dashboard.cell(row=analysis_row+5, column=1, value="第3四分位:")
ws_dashboard.cell(row=analysis_row+5, column=2, value="=QUARTILE('計算シート'!F:F,3)")
ws_dashboard.cell(row=analysis_row+5, column=2).number_format = "#,##0"
# 条件付き書式の追加
# 売上データシートに条件付き書式
ws_sales.conditional_formatting.add("F2:F201",
ColorScaleRule(start_type="percentile", start_value=10, start_color="FF6B6B",
mid_type="percentile", mid_value=50, mid_color="FFD93D",
end_type="percentile", end_value=90, end_color="6BCB77"))
# 計算シートに条件付き書式
ws_calc.conditional_formatting.add("L2:L201",
DataBarRule(start_type="min", end_type="max",
color="4472C4", showValue=True, minLength=None, maxLength=None))
# 月次集計にアイコンセット
ws_monthly.conditional_formatting.add("I2:I13",
IconSetRule("3Arrows", "percent", [33, 67], showValue=True, reverse=False))
# シート7: 営業担当分析
ws_sales_person = wb.create_sheet("営業担当分析")
# ヘッダー
sp_headers = ["営業担当", "売上件数", "総売上", "目標達成率", "成約率", "顧客満足度", "生産性指数", "ボーナス係数"]
for col, header in enumerate(sp_headers, 1):
ws_sales_person.cell(row=1, column=col, value=header)
ws_sales_person.cell(row=1, column=col).font = Font(bold=True)
ws_sales_person.cell(row=1, column=col).fill = PatternFill(start_color="E74C3C", end_color="E74C3C", fill_type="solid")
ws_sales_person.cell(row=1, column=col).font = Font(color="FFFFFF", bold=True)
for idx, person in enumerate(sales_persons, 2):
ws_sales_person.cell(row=idx, column=1, value=person)
# 売上件数
ws_sales_person.cell(row=idx, column=2, value=f"=COUNTIF('売上データ'!K:K,A{idx})")
# 総売上
ws_sales_person.cell(row=idx, column=3, value=f"=SUMIF('売上データ'!K:K,A{idx},'計算シート'!F:F)")
# 目標達成率 (個人目標を2000万と仮定)
ws_sales_person.cell(row=idx, column=4, value=f"=C{idx}/20000000")
# 成約率 (ランダム)
ws_sales_person.cell(row=idx, column=5, value=f"=RANDBETWEEN(15,35)/100")
# 顧客満足度 (ランダム)
ws_sales_person.cell(row=idx, column=6, value=f"=RANDBETWEEN(75,95)/100")
# 生産性指数
ws_sales_person.cell(row=idx, column=7, value=f"=D{idx}*E{idx}*F{idx}")
# ボーナス係数
ws_sales_person.cell(row=idx, column=8, value=f"=IF(D{idx}>1,1.5,IF(D{idx}>0.8,1.2,IF(D{idx}>0.6,1,0.8)))")
# シート8: 財務分析
ws_finance = wb.create_sheet("財務分析")
# ヘッダー
fin_headers = ["項目", "Q1", "Q2", "Q3", "Q4", "年間合計", "前年比", "計画比", "達成率"]
for col, header in enumerate(fin_headers, 1):
ws_finance.cell(row=1, column=col, value=header)
ws_finance.cell(row=1, column=col).font = Font(bold=True)
ws_finance.cell(row=1, column=col).fill = PatternFill(start_color="2E7D32", end_color="2E7D32", fill_type="solid")
ws_finance.cell(row=1, column=col).font = Font(color="FFFFFF", bold=True)
# 財務項目
fin_items = ["売上高", "売上原価", "粗利益", "販管費", "営業利益", "経常利益", "純利益"]
for idx, item in enumerate(fin_items, 2):
ws_finance.cell(row=idx, column=1, value=item)
if item == "売上高":
# 四半期ごとの売上
ws_finance.cell(row=idx, column=2, value="=SUM('月次集計'!C2:C4)") # Q1
ws_finance.cell(row=idx, column=3, value="=SUM('月次集計'!C5:C7)") # Q2
ws_finance.cell(row=idx, column=4, value="=SUM('月次集計'!C8:C10)") # Q3
ws_finance.cell(row=idx, column=5, value="=SUM('月次集計'!C11:C13)") # Q4
elif item == "売上原価":
ws_finance.cell(row=idx, column=2, value=f"=B{idx-1}*0.6")
ws_finance.cell(row=idx, column=3, value=f"=C{idx-1}*0.6")
ws_finance.cell(row=idx, column=4, value=f"=D{idx-1}*0.6")
ws_finance.cell(row=idx, column=5, value=f"=E{idx-1}*0.6")
elif item == "粗利益":
ws_finance.cell(row=idx, column=2, value=f"=B{idx-2}-B{idx-1}")
ws_finance.cell(row=idx, column=3, value=f"=C{idx-2}-C{idx-1}")
ws_finance.cell(row=idx, column=4, value=f"=D{idx-2}-D{idx-1}")
ws_finance.cell(row=idx, column=5, value=f"=E{idx-2}-E{idx-1}")
elif item == "販管費":
ws_finance.cell(row=idx, column=2, value=f"=B{idx-3}*0.25")
ws_finance.cell(row=idx, column=3, value=f"=C{idx-3}*0.25")
ws_finance.cell(row=idx, column=4, value=f"=D{idx-3}*0.25")
ws_finance.cell(row=idx, column=5, value=f"=E{idx-3}*0.25")
elif item == "営業利益":
ws_finance.cell(row=idx, column=2, value=f"=B{idx-2}-B{idx-1}")
ws_finance.cell(row=idx, column=3, value=f"=C{idx-2}-C{idx-1}")
ws_finance.cell(row=idx, column=4, value=f"=D{idx-2}-D{idx-1}")
ws_finance.cell(row=idx, column=5, value=f"=E{idx-2}-E{idx-1}")
elif item == "経常利益":
ws_finance.cell(row=idx, column=2, value=f"=B{idx-1}*0.95")
ws_finance.cell(row=idx, column=3, value=f"=C{idx-1}*0.95")
ws_finance.cell(row=idx, column=4, value=f"=D{idx-1}*0.95")
ws_finance.cell(row=idx, column=5, value=f"=E{idx-1}*0.95")
elif item == "純利益":
ws_finance.cell(row=idx, column=2, value=f"=B{idx-1}*0.7")
ws_finance.cell(row=idx, column=3, value=f"=C{idx-1}*0.7")
ws_finance.cell(row=idx, column=4, value=f"=D{idx-1}*0.7")
ws_finance.cell(row=idx, column=5, value=f"=E{idx-1}*0.7")
# 年間合計
ws_finance.cell(row=idx, column=6, value=f"=SUM(B{idx}:E{idx})")
# 前年比 (ランダム)
ws_finance.cell(row=idx, column=7, value=f"=RANDBETWEEN(90,120)/100")
# 計画比 (ランダム)
ws_finance.cell(row=idx, column=8, value=f"=RANDBETWEEN(85,115)/100")
# 達成率
ws_finance.cell(row=idx, column=9, value=f"=H{idx}")
# シート9: 予測モデル
ws_forecast = wb.create_sheet("予測モデル")
# ヘッダー
forecast_headers = ["月", "実績", "線形予測", "指数平滑", "季節調整", "ARIMA", "アンサンブル予測", "信頼区間下限", "信頼区間上限", "予測精度"]
for col, header in enumerate(forecast_headers, 1):
ws_forecast.cell(row=1, column=col, value=header)
ws_forecast.cell(row=1, column=col).font = Font(bold=True)
ws_forecast.cell(row=1, column=col).fill = PatternFill(start_color="9C27B0", end_color="9C27B0", fill_type="solid")
ws_forecast.cell(row=1, column=col).font = Font(color="FFFFFF", bold=True)
# 予測データ
for month in range(1, 25): # 24ヶ月分
row = month + 1
ws_forecast.cell(row=row, column=1, value=f"2024/{(month-1)%12+1:02d}")
if month <= 12:
# 実績データ参照
ws_forecast.cell(row=row, column=2, value=f"='月次集計'!C{month+1}")
else:
# 予測期間
ws_forecast.cell(row=row, column=2, value="")
# 線形予測
if month <= 12:
ws_forecast.cell(row=row, column=3, value=f"=FORECAST({month},'月次集計'!$C$2:$C$13,ROW('月次集計'!$C$2:$C$13))")
else:
ws_forecast.cell(row=row, column=3, value=f"=FORECAST({month},'月次集計'!$C$2:$C$13,ROW('月次集計'!$C$2:$C$13))*1.05")
# 指数平滑 (簡易版)
if row == 2:
ws_forecast.cell(row=row, column=4, value=f"=B{row}")
elif month <= 12:
ws_forecast.cell(row=row, column=4, value=f"=0.3*B{row}+0.7*D{row-1}")
else:
ws_forecast.cell(row=row, column=4, value=f"=D{row-1}*1.02")
# 季節調整
ws_forecast.cell(row=row, column=5, value=f"=C{row}*(1+SIN(2*PI()*{(month-1)%12}/12)*0.15)")
# ARIMA (簡易版)
if row <= 3:
ws_forecast.cell(row=row, column=6, value=f"=C{row}")
else:
ws_forecast.cell(row=row, column=6, value=f"=0.5*C{row}+0.3*C{row-1}+0.2*C{row-2}")
# アンサンブル予測
ws_forecast.cell(row=row, column=7, value=f"=(C{row}+D{row}+E{row}+F{row})/4")
# 信頼区間
ws_forecast.cell(row=row, column=8, value=f"=G{row}*0.9")
ws_forecast.cell(row=row, column=9, value=f"=G{row}*1.1")
# 予測精度
if month <= 12 and row > 2:
ws_forecast.cell(row=row, column=10, value=f"=1-ABS((B{row}-G{row})/B{row})")
else:
ws_forecast.cell(row=row, column=10, value="")
# シート10: リスク分析
ws_risk = wb.create_sheet("リスク分析")
# ヘッダー
risk_headers = ["リスク項目", "発生確率", "影響度", "リスク値", "対策コスト", "期待損失", "ROI", "優先順位"]
for col, header in enumerate(risk_headers, 1):
ws_risk.cell(row=1, column=col, value=header)
ws_risk.cell(row=1, column=col).font = Font(bold=True)
ws_risk.cell(row=1, column=col).fill = PatternFill(start_color="D32F2F", end_color="D32F2F", fill_type="solid")
ws_risk.cell(row=1, column=col).font = Font(color="FFFFFF", bold=True)
risks = [
"市場競争激化",
"供給チェーン混乱",
"為替変動",
"技術的陳腐化",
"規制変更",
"サイバーセキュリティ",
"人材流出"
]
for idx, risk in enumerate(risks, 2):
ws_risk.cell(row=idx, column=1, value=risk)
# 発生確率
ws_risk.cell(row=idx, column=2, value=f"=RANDBETWEEN(10,80)/100")
# 影響度 (1-10スケール)
ws_risk.cell(row=idx, column=3, value=f"=RANDBETWEEN(3,10)")
# リスク値
ws_risk.cell(row=idx, column=4, value=f"=B{idx}*C{idx}")
# 対策コスト
ws_risk.cell(row=idx, column=5, value=f"=RANDBETWEEN(100000,1000000)")
# 期待損失
ws_risk.cell(row=idx, column=6, value=f"=B{idx}*C{idx}*1000000")
# ROI
ws_risk.cell(row=idx, column=7, value=f"=(F{idx}-E{idx})/E{idx}")
# 優先順位
ws_risk.cell(row=idx, column=8, value=f"=RANK(D{idx},D$2:D$8,0)")
# 列幅の自動調整
for sheet in wb.worksheets:
for column_cells in sheet.columns:
try:
length = max(len(str(cell.value or "")) for cell in column_cells if cell.value is not None)
if hasattr(column_cells[0], 'column_letter'):
sheet.column_dimensions[column_cells[0].column_letter].width = min(length + 2, 30)
except (ValueError, AttributeError):
continue
# ファイルを保存
filename = "complex_excel_workbook.xlsx"
wb.save(filename)
print(f"複雑なExcelワークブック '{filename}' を作成しました。")
print(f"作成されたシート数: {len(wb.worksheets)}")
print(f"シート名: {', '.join([ws.title for ws in wb.worksheets])}")
return filename
if __name__ == "__main__":
create_complex_workbook()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment