Skip to content

Instantly share code, notes, and snippets.

@feo52
Last active September 24, 2024 17:09
Show Gist options
  • Save feo52/e538a8134112d98166f0cc1ee81f6561 to your computer and use it in GitHub Desktop.
Save feo52/e538a8134112d98166f0cc1ee81f6561 to your computer and use it in GitHub Desktop.
Python pywin32(win32com) : Excel Pivot Table
ID Meta Type Name Date Count
21 hoge 2220 nico 2020/2/22 1
22 fuga 2220 nico 2021/2/22 2
23 piyo 2220 nico 2022/2/22 3
24 hoge 2221 nuko 2020/2/22 4
25 fuga 2221 nuko 2021/2/22 5
26 piyo 2221 nuko 2022/2/22 6
27 hoge 2222 neko 2020/2/22 7
28 fuga 2222 neko 2021/2/22 8
29 piyo 2222 neko 2022/2/22 9
# coding:utf-8
import os
import win32com.client
import win32con
import win32gui
def main():
# ------------------------------------------------------------------
# Excelの定数の設定
# ------------------------------------------------------------------
# https://docs.microsoft.com/en-us/office/vba/api/excel(enumerations)
# https://docs.microsoft.com/ja-jp/office/vba/api/excel(enumerations)
# ------------------------------------------------------------------
# Excelの定数を取得する方法もあるようです。
# https://stackoverflow.com/questions/28264548/
# https://stackoverflow.com/questions/75154736/
# https://stackoverflow.com/questions/50127959/
# https://stackoverflow.com/questions/48257308/
# https://wacky.hatenadiary.com/entry/20091011/1255240572
# win32com.client.gencache.EnsureDispatch("Excel.Application")
# ------------------------------------------------------------------
# Excel Enum XlFindLookIn
# ------------------------------------------------------------------
xlComments = -4144
xlCommentsThreaded = -4184
xlFormulas = -4123
xlValues = -4163
# ------------------------------------------------------------------
# Excel Enum XlLookAt
# ------------------------------------------------------------------
xlPart = 2
xlWhole = 1
# ------------------------------------------------------------------
# Excel Enum XlReferenceStyle
# ------------------------------------------------------------------
xlA1 = 1
xlR1C1 = -4150
# ------------------------------------------------------------------
# Excel Enum XlReferenceType
# ------------------------------------------------------------------
xlAbsolute = 1
xlAbsRowRelColumn = 2
xlRelRowAbsColumn = 3
xlRelative = 4
# ------------------------------------------------------------------
# Excel Enum XlSearchDirection
# ------------------------------------------------------------------
xlNext = 1
xlPrevious = 2
# ------------------------------------------------------------------
# Excel Enum XlSearchOrder
# ------------------------------------------------------------------
xlByColumns = 2
xlByRows = 1
# ------------------------------------------------------------------
# Excel Enum XlConsolidationFunction
# ------------------------------------------------------------------
xlAverage = -4106
xlCount = -4112
xlCountNums = -4113
xlDistinctCount = 11
xlMax = -4136
xlMin = -4139
xlProduct = -4149
xlStDev = -4155
xlStDevP = -4156
xlSum = -4157
xlUnknown = 1000
xlVar = -4164
xlVarP = -4165
# ------------------------------------------------------------------
# Excel Enum XlLayoutRowType
# ------------------------------------------------------------------
xlCompactRow = 0
xlOutlineRow = 2
xlTabularRow = 1
# ------------------------------------------------------------------
# Excel Enum XlPivotFieldOrientation
# ------------------------------------------------------------------
xlColumnField = 2
xlDataField = 4
xlHidden = 0
xlPageField = 3
xlRowField = 1
# ------------------------------------------------------------------
# Excel Enum XlPivotFieldRepeatLabels
# ------------------------------------------------------------------
xlDoNotRepeatLabels = 1
xlRepeatLabels = 2
# ------------------------------------------------------------------
# Excel Enum XlPivotTableMissingItems
# ------------------------------------------------------------------
xlMissingItemsDefault = -1
xlMissingItemsMax = 32500
xlMissingItemsMax2 = 1048576
xlMissingItemsNone = 0
# ------------------------------------------------------------------
# Excel Enum XlPivotTableSourceType
# ------------------------------------------------------------------
xlConsolidation = 3
xlDatabase = 1
xlExternal = 2
xlPivotTable = -4148
xlScenario = 4
# ------------------------------------------------------------------
# Excel Enum XlSlicerCacheType
# ------------------------------------------------------------------
xlSlicer = 1
xlTimeline = 2
# ------------------------------------------------------------------
# Excel Enum XlSlicerSort
# ------------------------------------------------------------------
xlSlicerSortAscending = 2
xlSlicerSortDataSourceOrder = 1
xlSlicerSortDescending = 3
# ------------------------------------------------------------------
# Excel Enum XlSortOrder
# ------------------------------------------------------------------
xlAscending = 1
xlDescending = 2
xlManual = -4135
# ------------------------------------------------------------------
# Excel Enum XlTimelineLevel
# ------------------------------------------------------------------
xlTimelineLevelYears = 0
xlTimelineLevelQuarters = 1
xlTimelineLevelMonths = 2
xlTimelineLevelDays = 3
# ------------------------------------------------------------------
# Excel Enum XlPivotFilterType
# ------------------------------------------------------------------
xlBefore = 31
xlBeforeOrEqualTo = 32
xlAfter = 33
xlAfterOrEqualTo = 34
xlAllDatesInPeriodJanuary = 57
xlAllDatesInPeriodFebruary = 58
xlAllDatesInPeriodMarch = 59
xlAllDatesInPeriodApril = 60
xlAllDatesInPeriodMay = 61
xlAllDatesInPeriodJune = 62
xlAllDatesInPeriodJuly = 63
xlAllDatesInPeriodAugust = 64
xlAllDatesInPeriodSeptember = 65
xlAllDatesInPeriodOctober = 66
xlAllDatesInPeriodNovember = 67
xlAllDatesInPeriodDecember = 68
xlAllDatesInPeriodQuarter1 = 53
xlAllDatesInPeriodQuarter2 = 54
xlAllDatesInPeriodQuarter3 = 55
xlAllDatesInPeriodQuarter4 = 56
xlBottomCount = 2
xlBottomPercent = 4
xlBottomSum = 6
xlCaptionBeginsWith = 17
xlCaptionContains = 21
xlCaptionDoesNotBeginWith = 18
xlCaptionDoesNotContain = 22
xlCaptionDoesNotEndWith = 20
xlCaptionDoesNotEqual = 16
xlCaptionEndsWith = 19
xlCaptionEquals = 15
xlCaptionIsBetween = 27
xlCaptionIsGreaterThan = 23
xlCaptionIsGreaterThanOrEqualTo = 24
xlCaptionIsLessThan = 25
xlCaptionIsLessThanOrEqualTo = 26
xlCaptionIsNotBetween = 28
xlDateBetween = 35
xlDateLastMonth = 45
xlDateLastQuarter = 48
xlDateLastWeek = 42
xlDateLastYear = 51
xlDateNextMonth = 43
xlDateNextQuarter = 46
xlDateNextWeek = 40
xlDateNextYear = 49
xlDateThisMonth = 44
xlDateThisQuarter = 47
xlDateThisWeek = 41
xlDateThisYear = 50
xlDateToday = 38
xlDateTomorrow = 37
xlDateYesterday = 39
xlNotSpecificDate = 30
xlSpecificDate = 29
xlTopCount = 1
xlTopPercent = 3
xlTopSum = 5
xlValueDoesNotEqual = 8
xlValueEquals = 7
xlValueIsBetween = 13
xlValueIsGreaterThan = 9
xlValueIsGreaterThanOrEqualTo = 10
xlValueIsLessThan = 11
xlValueIsLessThanOrEqualTo = 12
xlValueIsNotBetween = 14
xlYearToDate = 52
# ------------------------------------------------------------------
# Excel起動
xlApp = win32com.client.Dispatch("Excel.Application")
# ExcelのWindow最大化
win32gui.ShowWindow(xlApp.hwnd, win32con.SW_MAXIMIZE)
# Excel表示
xlApp.Visible = 1
# Excelファイルオープン
wb = xlApp.Workbooks.Open(f"{os.getcwd()}\\sample.csv")
# Excelシートオブジェクト
ws = wb.Worksheets(1)
# ------------------------------------------------------------------
# 指定したシートを選択
ws.Activate()
# シートの追加
ws = ws.Parent.Worksheets.Add()
# 指定したシートを選択
ws.Activate()
# ------------------------------------------------------------------
# ピボットテーブルの作成
# ------------------------------------------------------------------
# ピボットテーブルのキャッシュの作成
pcache = wb.PivotCaches().Create(SourceType=xlDatabase, SourceData="sample!A:F")
# ピボットテーブルの作成
ptable = pcache.CreatePivotTable(TableDestination=ws.Range("A1"), TableName="ピボットテーブル1")
# ピボットテーブルに集計フィールドを挿入
ptable.CalculatedFields().Add(Name="Twice", Formula="=Count*2")
# ------------------------------------------------------------------
# ピボットテーブルのフィールド
# ------------------------------------------------------------------
# ピボットテーブルのフィルターの設定
ptable.PivotFields("ID").Orientation = xlPageField
# ピボットテーブルのフィルターの設定
ptable.PivotFields("Meta").Orientation = xlPageField
# ピボットテーブルのフィルターの位置の設定
ptable.PivotFields("Meta").Position = 1
# ピボットテーブルのフィールドの行の設定
ptable.PivotFields("Type").Orientation = xlRowField
# ピボットテーブルのフィールドの行の設定
ptable.PivotFields("Name").Orientation = xlRowField
# ピボットテーブルのフィールドの列の設定
ptable.PivotFields("Date").Orientation = xlColumnField
# ピボットテーブルのCountを合計
pfield1 = ptable.AddDataField(Field=ptable.PivotFields("Count"), Caption="SumCount", Function=xlSum)
# ピボットテーブルのTwiceを合計
pfield2 = ptable.AddDataField(Field=ptable.PivotFields("Twice"), Caption="SumTwice", Function=xlSum)
# ------------------------------------------------------------------
# ピボットテーブルのレイアウトとオプションの設定
# ------------------------------------------------------------------
# ピボットテーブルのレイアウト:表形式で表示
ptable.RowAxisLayout(RowLayout=xlTabularRow)
# ピボットテーブルのレイアウト:アイテムのラベルをすべて繰り返す
ptable.RepeatAllLabels(Repeat=xlRepeatLabels)
# ピボットテーブルのオプション:データソースから削除されたアイテムを保持しない
# ptable(PivotTable)ではなくpcache(PivotCache)のプロパティであることに注意
pcache.MissingItemsLimit = xlMissingItemsNone
# ピボットテーブルのオプション:更新時に列幅を自動調整しない
ptable.HasAutoFormat = False
# ピボットテーブルのオプション:更新時にセル書式を保持しない
ptable.PreserveFormatting = False
# ピボットテーブルのオプション:ファイルに元のデータを保持しない
ptable.SaveData = False
# ピボットテーブルのオプション:詳細を表示可能にしない
ptable.EnableDrilldown = False
# ピボットテーブルのオプション:行の総計を表示しない
ptable.RowGrand = False
# ピボットテーブルのオプション:列の総計を表示しない
ptable.ColumnGrand = False
# ------------------------------------------------------------------
# ピボットテーブルの設定
# ------------------------------------------------------------------
# ピボットテーブルの小計を非表示
ptable.PivotFields("Type").Subtotals = tuple(False for _ in range(12))
ptable.PivotFields("Name").Subtotals = tuple(False for _ in range(12))
ptable.PivotFields("Date").Subtotals = tuple(False for _ in range(12))
# ピボットテーブルのIDの単一のアイテムを設定
ptable.PivotFields("ID").ClearAllFilters()
ptable.PivotFields("ID").CurrentPage = "(All)"
ptable.PivotFields("ID").CurrentPage = "(blank)"
ptable.PivotFields("ID").CurrentPage = 21
ptable.PivotFields("ID").CurrentPage = 22
ptable.PivotFields("ID").CurrentPage = 23
# ピボットテーブルのIDの複数のアイテムを設定
ptable.PivotFields("ID").ClearAllFilters()
ptable.PivotFields("ID").EnableMultiplePageItems = True
ptable.PivotFields("ID").PivotItems("21").Visible = True
ptable.PivotFields("ID").PivotItems("22").Visible = True
ptable.PivotFields("ID").PivotItems("23").Visible = True
ptable.PivotFields("ID").PivotItems("24").Visible = False
ptable.PivotFields("ID").PivotItems("25").Visible = False
ptable.PivotFields("ID").PivotItems("26").Visible = False
ptable.PivotFields("ID").PivotItems("27").Visible = False
ptable.PivotFields("ID").PivotItems("28").Visible = False
ptable.PivotFields("ID").PivotItems("29").Visible = False
ptable.PivotFields("ID").PivotItems("(blank)").Visible = False
# ピボットテーブルのIDの複数のアイテムを設定
ptable.PivotFields("ID").ClearAllFilters()
ptable.PivotFields("ID").EnableMultiplePageItems = True
# 全てのPivotItemのVisibleをFalseにするとエラーになるので、
# ひとまずは空欄以外の全てのPivotItemのVisibleをFalseする。
for pi in ptable.PivotFields("ID").PivotItems():
pi.Visible = False if pi.Name != "(blank)" else True
# 必要なPivotItemのVisibleをTrueにする。
ptable.PivotFields("ID").PivotItems("21").Visible = True
ptable.PivotFields("ID").PivotItems("22").Visible = True
ptable.PivotFields("ID").PivotItems("23").Visible = True
# 空欄のPivotItemが不要であれば空欄のPivotItemのVisibleをFalseにする。
ptable.PivotFields("ID").PivotItems("(blank)").Visible = False
# ------------------------------------------------------------------
# ピボットテーブルの設定
# ------------------------------------------------------------------
# ピボットテーブルのIDの複数のアイテムを設定
# 指定のItemはTrue/指定以外のItemはFalse
ptable.PivotFields("ID").ClearAllFilters()
ptable.PivotFields("ID").EnableMultiplePageItems = True
for pi in ptable.PivotFields("ID").PivotItems():
pi.Visible = pi.Name in ["21", "22", "23", "29", "(blank)"]
# ピボットテーブルのIDの複数のアイテムを設定
# 指定のItemはFalse/指定以外のItemはTrue
# TrueになるItemが0個になってしまうとError
ptable.PivotFields("ID").ClearAllFilters()
ptable.PivotFields("ID").EnableMultiplePageItems = True
for pi in ptable.PivotFields("ID").PivotItems():
pi.Visible = pi.Name not in ["21", "22", "23", "29", "(blank)"]
# ピボットテーブルのIDの複数のアイテムを設定
# 指定のItemはTrue/指定以外のItemは変更しない
# ptable.PivotFields("ID").ClearAllFilters()
# ptable.PivotFields("ID").EnableMultiplePageItems = True
for pi in ptable.PivotFields("ID").PivotItems():
if pi.Name in ["21", "22"]:
pi.Visible = True
# ピボットテーブルのIDの複数のアイテムを設定
# 指定のItemはFalse/指定以外のItemは変更しない
# TrueになるItemが0個になってしまうとError
# ptable.PivotFields("ID").ClearAllFilters()
# ptable.PivotFields("ID").EnableMultiplePageItems = True
for pi in ptable.PivotFields("ID").PivotItems():
if pi.Name in ["25", "26"]:
pi.Visible = False
# ------------------------------------------------------------------
# ピボットテーブルの設定
# ------------------------------------------------------------------
# 上記までの処理方法は
# ピボットテーブルがループ毎に更新されかねない為
# Item数やData量が多い場合は処理に時間が掛かる…
# コンソールに進捗を出力して気を紛らす場合は以下
# ピボットテーブルのIDの複数のアイテムを設定
# 指定のItemはTrue/指定以外のItemはFalse
ptable.PivotFields("ID").ClearAllFilters()
ptable.PivotFields("ID").EnableMultiplePageItems = True
for i, pi in enumerate(lst := ptable.PivotFields("ID").PivotItems()):
pi.Visible = pi.Name in ["21", "22", "23", "29", "(blank)"]
print(f"{i+1:04}/{len(lst):04}")
# ピボットテーブルのIDの複数のアイテムを設定
# 指定のItemはFalse/指定以外のItemはTrue
# TrueになるItemが0個になってしまうとError
ptable.PivotFields("ID").ClearAllFilters()
ptable.PivotFields("ID").EnableMultiplePageItems = True
for i, pi in enumerate(lst := ptable.PivotFields("ID").PivotItems()):
pi.Visible = pi.Name not in ["21", "22", "23", "29", "(blank)"]
print(f"{i+1:04}/{len(lst):04}")
# ピボットテーブルのIDの複数のアイテムを設定
# 指定のItemはTrue/指定以外のItemは変更しない
# ptable.PivotFields("ID").ClearAllFilters()
# ptable.PivotFields("ID").EnableMultiplePageItems = True
for i, pi in enumerate(lst := ptable.PivotFields("ID").PivotItems()):
if pi.Name in ["21", "22"]:
pi.Visible = True
print(f"{i+1:04}/{len(lst):04}")
# ピボットテーブルのIDの複数のアイテムを設定
# 指定のItemはFalse/指定以外のItemは変更しない
# TrueになるItemが0個になってしまうとError
# ptable.PivotFields("ID").ClearAllFilters()
# ptable.PivotFields("ID").EnableMultiplePageItems = True
for i, pi in enumerate(lst := ptable.PivotFields("ID").PivotItems()):
if pi.Name in ["25", "26"]:
pi.Visible = False
print(f"{i+1:04}/{len(lst):04}")
# ピボットテーブルのIDのフィルターの解除
ptable.PivotFields("ID").ClearAllFilters()
# ------------------------------------------------------------------
# ピボットテーブルの設定とデータソースの変更
# ------------------------------------------------------------------
# 上記までの処理方法は
# ピボットテーブルがループ毎に更新されかねない為
# Item数やData量が多い場合は処理に時間が掛かる…
# ピボットテーブルのみの解決方法が思い付かない為
# データソースにヘルパー列を追加して対応する方法
def PivotFieldSetVisibleItemsListWithDynamicArrayFormula(pf, visible, primary=None, prefix="", suffix="Visible"):
pt = pf.Parent
pc = pt.PivotCache()
ws = pt.Parent
wb = ws.Parent
ap = ws.Application
sd = ap.ConvertFormula(pc.SourceData, xlR1C1, xlA1, xlRelative)
rg = ap.Evaluate(sd)
SourceDataRange = rg
# 数式を作成
rg = SourceDataRange
rg = rg.find(pf.Name, rg.GetResize(1, 1), xlValues, xlWhole, xlByRows, xlNext, True)
rg = rg.EntireColumn
covered = rg.GetAddress(False, False)
rg = SourceDataRange
rg = rg.GetResize(1, 1)
rg = rg.EntireColumn
primary = primary or rg.GetAddress(False, False)
formula = f'=SWITCH(FILTER({covered},NOT(ISBLANK({primary}))),"{pf.Name}","{prefix}{pf.Name}{suffix}",'
formula += "".join([(f"{v},1," if type(v) is not str else f'"{v}",1,') for v in visible])
formula += "0)"
# 数式を入力
rg = SourceDataRange
cc = rg.Columns.Count
rg = rg.GetResize(1, 1)
rg = rg.GetOffset(0, cc)
rg.Formula2 = formula
# ピボットテーブルのキャッシュを変更
rg = SourceDataRange
rc = rg.Rows.Count
cc = rg.Columns.Count
rg = rg.GetResize(rc, cc + 1)
pc = wb.PivotCaches().Create(SourceType=xlDatabase, SourceData=rg)
pt.ChangePivotCache(pc)
# ピボットテーブルのフィルターを追加
pt.PivotFields(f"{prefix}{pf.Name}{suffix}").Orientation = xlPageField
pt.PivotFields(f"{prefix}{pf.Name}{suffix}").Position = 1
# ピボットテーブルのフィルターを設定
pt.PivotFields(f"{prefix}{pf.Name}{suffix}").ClearAllFilters()
pt.PivotFields(f"{prefix}{pf.Name}{suffix}").CurrentPage = 1
return pt, pt.PivotCache()
# データソースにヘルパー列として動的配列数式追加
# ピボットテーブルのフィルターを動的配列数式の結果が1で表示
# 指定のItemは1/指定以外のItemは0
# 指定のItemに(blank)の指定は不可
# 動的配列数式動作環境Excel2021~
pf = ptable.PivotFields("ID")
visible = [21, 22, 23, 29]
# primary = "A:A" # データソースの空欄の無い列を指定。省略すると一番左側の列を使用。
# ptable, pcache = PivotFieldSetVisibleItemsListWithDynamicArrayFormula(pf, visible, primary)
ptable, pcache = PivotFieldSetVisibleItemsListWithDynamicArrayFormula(pf, visible)
ptable.PivotFields("IDVisible").Position = 2
# ピボットテーブルのフィルターを解除
ptable.PivotFields("IDVisible").ClearAllFilters()
# データソースにヘルパー列として動的配列数式追加
# ピボットテーブルのフィルターを動的配列数式の結果が1で表示
# 指定のItemは1/指定以外のItemは0
# 指定のItemに(blank)の指定は不可
# 動的配列数式動作環境Excel2021~
pf = ptable.PivotFields("Meta")
visible = ["hoge", "piyo"]
# primary = "A:A" # データソースの空欄の無い列を指定。省略すると一番左側の列を使用。
# ptable, pcache = PivotFieldSetVisibleItemsListWithDynamicArrayFormula(pf, visible, primary)
ptable, pcache = PivotFieldSetVisibleItemsListWithDynamicArrayFormula(pf, visible)
# ピボットテーブルのフィルターを解除
ptable.PivotFields("MetaVisible").ClearAllFilters()
# ------------------------------------------------------------------
# ピボットテーブルの設定
# ------------------------------------------------------------------
# ピボットテーブルのTypeの順序を昇順に設定
ptable.PivotFields("Type").AutoSort(Order=xlAscending, Field="Type")
# ピボットテーブルのTypeを0より大きいに設定
ptable.PivotFields("Type").PivotFilters.Add2(Type=xlCaptionIsGreaterThan, DataField=None, Value1=0)
# ピボットテーブルのTypeを合計が10より大きいに設定
ptable.PivotFields("Type").PivotFilters.Add2(Type=xlValueIsGreaterThan, DataField=ptable.PivotFields("SumCount"), Value1=10)
# ピボットテーブルのTypeの2222を含まないよう設定
ptable.PivotFields("Type").PivotItems("2222").Visible = False
# ピボットテーブルのTypeのフィルターの解除
ptable.PivotFields("Type").ClearAllFilters()
# ------------------------------------------------------------------
# ピボットテーブルの設定
# ------------------------------------------------------------------
# ピボットテーブルのDateの期間を設定
ptable.PivotFields("Date").PivotFilters.Add2(Type=xlDateBetween, DataField=None, Value1="1900/1/1", Value2="3000/1/1")
# ピボットテーブルのDateに自動的にグループ化を設定
ptable.PivotFields("Date").AutoGroup()
# ピボットテーブルのDateのグループ解除
drange = ptable.PivotFields("Date").DataRange
drange.Cells(1, 1).Ungroup()
# ピボットテーブルのDateに年と月のグループ化を設定
drange = ptable.PivotFields("Date").DataRange
drange.Cells(1, 1).Group(Start=True, End=True, By=None, Periods=tuple([False, False, False, False, True, False, True]))
# ピボットテーブルのDateの年の小計を非表示
ptable.PivotFields("年 (Date)").Subtotals = tuple(False for _ in range(12))
# ピボットテーブルのDateの年を非表示
ptable.PivotFields("年 (Date)").Orientation = xlHidden
# ピボットテーブルのDateのグループ解除
drange.Cells(1, 1).Ungroup()
# ------------------------------------------------------------------
# ピボットテーブルのスライサー
# ------------------------------------------------------------------
# ピボットテーブルのスライサーのキャッシュの作成
scache1 = wb.SlicerCaches.Add2(Source=ptable, SourceField="Type")
# ピボットテーブルのスライサーの作成
slicer1 = scache1.Slicers.Add(SlicerDestination=ws)
# ピボットテーブルのスライサーのキャッシュのフィルターの解除
scache1.ClearAllFilters()
# ピボットテーブルのスライサーのキャッシュの設定
scache1.SlicerItems("2222").Selected = False
# ピボットテーブルのスライサーの順序を昇順に設定
scache1.SortItems = xlSlicerSortAscending
# ピボットテーブルのスライサーの各種設定
slicer1.Name = "Type"
slicer1.Caption = "Type"
# ピボットテーブルのスライサーの位置設定
slicer1.Top = 0
slicer1.Left = 500
slicer1.Width = 100
slicer1.Height = 100
# ピボットテーブルのスライサーの位置設定
slicer1.Top = ws.Range("A20").Top
slicer1.Left = ws.Range("A20").Left
slicer1.Width = ws.Range("D30").Left - ws.Range("A20").Left
slicer1.Height = ws.Range("D30").Top - ws.Range("A20").Top
# ------------------------------------------------------------------
# ピボットテーブルのスライサー
# ------------------------------------------------------------------
# ピボットテーブルのスライサーのキャッシュの作成
scache2 = wb.SlicerCaches.Add2(Source=ptable, SourceField="Name")
# ピボットテーブルのスライサーの作成
slicer2 = scache2.Slicers.Add(SlicerDestination=ws)
# ピボットテーブルのスライサーのキャッシュのフィルターの解除
scache2.ClearAllFilters()
# ピボットテーブルのスライサーのキャッシュの設定
scache2.SlicerItems("nico").Selected = False
# ピボットテーブルのスライサーの順序を降順に設定
scache2.SortItems = xlSlicerSortDescending
# ピボットテーブルのスライサーの各種設定
slicer2.Name = "Name"
slicer2.Caption = "Name"
# ピボットテーブルのスライサーの位置設定
slicer2.Top = 0
slicer2.Left = 600
slicer2.Width = 100
slicer2.Height = 100
# ピボットテーブルのスライサーの位置設定
slicer2.Top = ws.Range("D20").Top
slicer2.Left = ws.Range("D20").Left
slicer2.Width = ws.Range("G30").Left - ws.Range("D20").Left
slicer2.Height = ws.Range("G30").Top - ws.Range("D20").Top
# ------------------------------------------------------------------
# ピボットテーブルのタイムライン
# ------------------------------------------------------------------
# ピボットテーブルのタイムラインのスライサーのキャッシュの作成
scache3 = wb.SlicerCaches.Add2(Source=ptable, SourceField="Date", Name="NativeTimeline_Date", SlicerCacheType=xlTimeline)
# ピボットテーブルのタイムラインのスライサーの作成
slicer3 = scache3.Slicers.Add(SlicerDestination=ws)
# ピボットテーブルのタイムラインのスライサーのキャッシュのフィルターの解除
scache3.ClearAllFilters()
# ピボットテーブルのタイムラインのスライサーのキャッシュの設定
scache3.TimelineState.SetFilterDateRange(StartDate="2020/1/1", EndDate="2030/1/1")
# ピボットテーブルのタイムラインのスライサーのレベルの設定
slicer3.TimelineViewState.Level = xlTimelineLevelMonths
# ピボットテーブルのタイムラインのスライサーの各種設定
slicer3.Name = "Date"
slicer3.Caption = "Date"
# ピボットテーブルのスライサーの位置設定
slicer3.Top = 0
slicer3.Left = 700
slicer3.Width = 300
slicer3.Height = 100
# ピボットテーブルのスライサーの位置設定
slicer3.Top = ws.Range("A30").Top
slicer3.Left = ws.Range("A30").Left
slicer3.Width = ws.Range("G40").Left - ws.Range("A30").Left
slicer3.Height = ws.Range("G40").Top - ws.Range("A30").Top
# ------------------------------------------------------------------
# ピボットテーブルの更新
# ------------------------------------------------------------------
# 指定のピボットテーブルの更新
pcache.Refresh()
# 指定のピボットテーブルの更新
ptable.RefreshTable()
# 指定のピボットテーブルの更新
ptable.Update()
# 全部のピボットテーブルの更新
wb.RefreshAll()
# ------------------------------------------------------------------
# 指定したシートを選択
ws.Activate()
# 指定したシートを選択
ws.Select()
# A1セルを選択
ws.Range("A1").Select()
# ------------------------------------------------------------------
# ブックを保存せずにクローズ
wb.Close(False)
# ------------------------------------------------------------------
# Excel終了
xlApp.Quit()
# ------------------------------------------------------------------
if __name__ == "__main__":
main()
# coding:utf-8
def main():
o = []
with open("sample.with.print.and.input.py", mode="rt", encoding="utf-8") as f:
for line in f:
if "# NO POST #" in line:
continue
line = line.replace('print("#', "#")
line = line.replace(' #")', "")
line = line.replace("#wb.Save()", " wb.Save()")
line = line.replace("#wb.Close(", " wb.Close(")
o.append(line)
with open("sample.py", mode="wt", encoding="utf-8") as f:
f.writelines(o)
if __name__ == "__main__":
main()
# coding:utf-8
import os
import win32com.client
import win32con
import win32gui
def main():
# ------------------------------------------------------------------
# Excelの定数の設定
# ------------------------------------------------------------------
# https://docs.microsoft.com/en-us/office/vba/api/excel(enumerations)
# https://docs.microsoft.com/ja-jp/office/vba/api/excel(enumerations)
# ------------------------------------------------------------------
# Excelの定数を取得する方法もあるようです。
# https://stackoverflow.com/questions/28264548/
# https://stackoverflow.com/questions/75154736/
# https://stackoverflow.com/questions/50127959/
# https://stackoverflow.com/questions/48257308/
# https://wacky.hatenadiary.com/entry/20091011/1255240572
# win32com.client.gencache.EnsureDispatch("Excel.Application")
# ------------------------------------------------------------------
# Excel Enum XlFindLookIn
# ------------------------------------------------------------------
xlComments = -4144
xlCommentsThreaded = -4184
xlFormulas = -4123
xlValues = -4163
# ------------------------------------------------------------------
# Excel Enum XlLookAt
# ------------------------------------------------------------------
xlPart = 2
xlWhole = 1
# ------------------------------------------------------------------
# Excel Enum XlReferenceStyle
# ------------------------------------------------------------------
xlA1 = 1
xlR1C1 = -4150
# ------------------------------------------------------------------
# Excel Enum XlReferenceType
# ------------------------------------------------------------------
xlAbsolute = 1
xlAbsRowRelColumn = 2
xlRelRowAbsColumn = 3
xlRelative = 4
# ------------------------------------------------------------------
# Excel Enum XlSearchDirection
# ------------------------------------------------------------------
xlNext = 1
xlPrevious = 2
# ------------------------------------------------------------------
# Excel Enum XlSearchOrder
# ------------------------------------------------------------------
xlByColumns = 2
xlByRows = 1
# ------------------------------------------------------------------
# Excel Enum XlConsolidationFunction
# ------------------------------------------------------------------
xlAverage = -4106
xlCount = -4112
xlCountNums = -4113
xlDistinctCount = 11
xlMax = -4136
xlMin = -4139
xlProduct = -4149
xlStDev = -4155
xlStDevP = -4156
xlSum = -4157
xlUnknown = 1000
xlVar = -4164
xlVarP = -4165
# ------------------------------------------------------------------
# Excel Enum XlLayoutRowType
# ------------------------------------------------------------------
xlCompactRow = 0
xlOutlineRow = 2
xlTabularRow = 1
# ------------------------------------------------------------------
# Excel Enum XlPivotFieldOrientation
# ------------------------------------------------------------------
xlColumnField = 2
xlDataField = 4
xlHidden = 0
xlPageField = 3
xlRowField = 1
# ------------------------------------------------------------------
# Excel Enum XlPivotFieldRepeatLabels
# ------------------------------------------------------------------
xlDoNotRepeatLabels = 1
xlRepeatLabels = 2
# ------------------------------------------------------------------
# Excel Enum XlPivotTableMissingItems
# ------------------------------------------------------------------
xlMissingItemsDefault = -1
xlMissingItemsMax = 32500
xlMissingItemsMax2 = 1048576
xlMissingItemsNone = 0
# ------------------------------------------------------------------
# Excel Enum XlPivotTableSourceType
# ------------------------------------------------------------------
xlConsolidation = 3
xlDatabase = 1
xlExternal = 2
xlPivotTable = -4148
xlScenario = 4
# ------------------------------------------------------------------
# Excel Enum XlSlicerCacheType
# ------------------------------------------------------------------
xlSlicer = 1
xlTimeline = 2
# ------------------------------------------------------------------
# Excel Enum XlSlicerSort
# ------------------------------------------------------------------
xlSlicerSortAscending = 2
xlSlicerSortDataSourceOrder = 1
xlSlicerSortDescending = 3
# ------------------------------------------------------------------
# Excel Enum XlSortOrder
# ------------------------------------------------------------------
xlAscending = 1
xlDescending = 2
xlManual = -4135
# ------------------------------------------------------------------
# Excel Enum XlTimelineLevel
# ------------------------------------------------------------------
xlTimelineLevelYears = 0
xlTimelineLevelQuarters = 1
xlTimelineLevelMonths = 2
xlTimelineLevelDays = 3
# ------------------------------------------------------------------
# Excel Enum XlPivotFilterType
# ------------------------------------------------------------------
xlBefore = 31
xlBeforeOrEqualTo = 32
xlAfter = 33
xlAfterOrEqualTo = 34
xlAllDatesInPeriodJanuary = 57
xlAllDatesInPeriodFebruary = 58
xlAllDatesInPeriodMarch = 59
xlAllDatesInPeriodApril = 60
xlAllDatesInPeriodMay = 61
xlAllDatesInPeriodJune = 62
xlAllDatesInPeriodJuly = 63
xlAllDatesInPeriodAugust = 64
xlAllDatesInPeriodSeptember = 65
xlAllDatesInPeriodOctober = 66
xlAllDatesInPeriodNovember = 67
xlAllDatesInPeriodDecember = 68
xlAllDatesInPeriodQuarter1 = 53
xlAllDatesInPeriodQuarter2 = 54
xlAllDatesInPeriodQuarter3 = 55
xlAllDatesInPeriodQuarter4 = 56
xlBottomCount = 2
xlBottomPercent = 4
xlBottomSum = 6
xlCaptionBeginsWith = 17
xlCaptionContains = 21
xlCaptionDoesNotBeginWith = 18
xlCaptionDoesNotContain = 22
xlCaptionDoesNotEndWith = 20
xlCaptionDoesNotEqual = 16
xlCaptionEndsWith = 19
xlCaptionEquals = 15
xlCaptionIsBetween = 27
xlCaptionIsGreaterThan = 23
xlCaptionIsGreaterThanOrEqualTo = 24
xlCaptionIsLessThan = 25
xlCaptionIsLessThanOrEqualTo = 26
xlCaptionIsNotBetween = 28
xlDateBetween = 35
xlDateLastMonth = 45
xlDateLastQuarter = 48
xlDateLastWeek = 42
xlDateLastYear = 51
xlDateNextMonth = 43
xlDateNextQuarter = 46
xlDateNextWeek = 40
xlDateNextYear = 49
xlDateThisMonth = 44
xlDateThisQuarter = 47
xlDateThisWeek = 41
xlDateThisYear = 50
xlDateToday = 38
xlDateTomorrow = 37
xlDateYesterday = 39
xlNotSpecificDate = 30
xlSpecificDate = 29
xlTopCount = 1
xlTopPercent = 3
xlTopSum = 5
xlValueDoesNotEqual = 8
xlValueEquals = 7
xlValueIsBetween = 13
xlValueIsGreaterThan = 9
xlValueIsGreaterThanOrEqualTo = 10
xlValueIsLessThan = 11
xlValueIsLessThanOrEqualTo = 12
xlValueIsNotBetween = 14
xlYearToDate = 52
# ------------------------------------------------------------------
print("# Excel起動 #")
xlApp = win32com.client.Dispatch("Excel.Application")
# print("press enter key to continue") # NO POST #
# input() # NO POST #
print("# ExcelのWindow最大化 #")
win32gui.ShowWindow(xlApp.hwnd, win32con.SW_MAXIMIZE)
# print("press enter key to continue") # NO POST #
# input() # NO POST #
print("# Excel表示 #")
xlApp.Visible = 1
# print("press enter key to continue") # NO POST #
# input() # NO POST #
print("# Excelファイルオープン #")
wb = xlApp.Workbooks.Open(f"{os.getcwd()}\\sample.csv")
# print("press enter key to continue") # NO POST #
# input() # NO POST #
print("# Excelシートオブジェクト #")
ws = wb.Worksheets(1)
# print("press enter key to continue") # NO POST #
# input() # NO POST #
# ------------------------------------------------------------------
print("# 指定したシートを選択 #")
ws.Activate()
# print("press enter key to continue") # NO POST #
# input() # NO POST #
print("# シートの追加 #")
ws = ws.Parent.Worksheets.Add()
# print("press enter key to continue") # NO POST #
# input() # NO POST #
print("# 指定したシートを選択 #")
ws.Activate()
print("press enter key to continue") # NO POST #
input() # NO POST #
# ------------------------------------------------------------------
# ピボットテーブルの作成
# ------------------------------------------------------------------
print("# ピボットテーブルのキャッシュの作成 #")
pcache = wb.PivotCaches().Create(SourceType=xlDatabase, SourceData="sample!A:F")
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルの作成 #")
ptable = pcache.CreatePivotTable(TableDestination=ws.Range("A1"), TableName="ピボットテーブル1")
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルに集計フィールドを挿入 #")
ptable.CalculatedFields().Add(Name="Twice", Formula="=Count*2")
print("press enter key to continue") # NO POST #
input() # NO POST #
# ------------------------------------------------------------------
# ピボットテーブルのフィールド
# ------------------------------------------------------------------
print("# ピボットテーブルのフィルターの設定 #")
ptable.PivotFields("ID").Orientation = xlPageField
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのフィルターの設定 #")
ptable.PivotFields("Meta").Orientation = xlPageField
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのフィルターの位置の設定 #")
ptable.PivotFields("Meta").Position = 1
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのフィールドの行の設定 #")
ptable.PivotFields("Type").Orientation = xlRowField
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのフィールドの行の設定 #")
ptable.PivotFields("Name").Orientation = xlRowField
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのフィールドの列の設定 #")
ptable.PivotFields("Date").Orientation = xlColumnField
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのCountを合計 #")
pfield1 = ptable.AddDataField(Field=ptable.PivotFields("Count"), Caption="SumCount", Function=xlSum)
print(pfield1.Caption) # NO POST #
print(pfield1.Name) # NO POST #
print(pfield1.Value) # NO POST #
print(pfield1.SourceName) # NO POST #
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのTwiceを合計 #")
pfield2 = ptable.AddDataField(Field=ptable.PivotFields("Twice"), Caption="SumTwice", Function=xlSum)
print(pfield2.Caption) # NO POST #
print(pfield2.Name) # NO POST #
print(pfield2.Value) # NO POST #
print(pfield2.SourceName) # NO POST #
print("press enter key to continue") # NO POST #
input() # NO POST #
# ------------------------------------------------------------------
# ピボットテーブルのレイアウトとオプションの設定
# ------------------------------------------------------------------
print("# ピボットテーブルのレイアウト:表形式で表示 #")
ptable.RowAxisLayout(RowLayout=xlTabularRow)
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのレイアウト:アイテムのラベルをすべて繰り返す #")
ptable.RepeatAllLabels(Repeat=xlRepeatLabels)
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのオプション:データソースから削除されたアイテムを保持しない #")
# ptable(PivotTable)ではなくpcache(PivotCache)のプロパティであることに注意
pcache.MissingItemsLimit = xlMissingItemsNone
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのオプション:更新時に列幅を自動調整しない #")
ptable.HasAutoFormat = False
print("press enter key to continue") # NO POST #
input() # NO POST #
# NO POST #
print("# 全列の横幅を設定 #") # NO POST #
ws.Cells.ColumnWidth = 12 # NO POST #
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのオプション:更新時にセル書式を保持しない #")
ptable.PreserveFormatting = False
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのオプション:ファイルに元のデータを保持しない #")
ptable.SaveData = False
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのオプション:詳細を表示可能にしない #")
ptable.EnableDrilldown = False
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのオプション:行の総計を表示しない #")
ptable.RowGrand = False
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのオプション:列の総計を表示しない #")
ptable.ColumnGrand = False
print("press enter key to continue") # NO POST #
input() # NO POST #
# ------------------------------------------------------------------
# ピボットテーブルの設定
# ------------------------------------------------------------------
print("# ピボットテーブルの小計を非表示 #")
ptable.PivotFields("Type").Subtotals = tuple(False for _ in range(12))
ptable.PivotFields("Name").Subtotals = tuple(False for _ in range(12))
ptable.PivotFields("Date").Subtotals = tuple(False for _ in range(12))
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのIDの単一のアイテムを設定 #")
ptable.PivotFields("ID").ClearAllFilters()
ptable.PivotFields("ID").CurrentPage = "(All)"
ptable.PivotFields("ID").CurrentPage = "(blank)"
ptable.PivotFields("ID").CurrentPage = 21
ptable.PivotFields("ID").CurrentPage = 22
ptable.PivotFields("ID").CurrentPage = 23
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのIDの複数のアイテムを設定 #")
ptable.PivotFields("ID").ClearAllFilters()
ptable.PivotFields("ID").EnableMultiplePageItems = True
ptable.PivotFields("ID").PivotItems("21").Visible = True
ptable.PivotFields("ID").PivotItems("22").Visible = True
ptable.PivotFields("ID").PivotItems("23").Visible = True
ptable.PivotFields("ID").PivotItems("24").Visible = False
ptable.PivotFields("ID").PivotItems("25").Visible = False
ptable.PivotFields("ID").PivotItems("26").Visible = False
ptable.PivotFields("ID").PivotItems("27").Visible = False
ptable.PivotFields("ID").PivotItems("28").Visible = False
ptable.PivotFields("ID").PivotItems("29").Visible = False
ptable.PivotFields("ID").PivotItems("(blank)").Visible = False
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのIDの複数のアイテムを設定 #")
ptable.PivotFields("ID").ClearAllFilters()
ptable.PivotFields("ID").EnableMultiplePageItems = True
# 全てのPivotItemのVisibleをFalseにするとエラーになるので、
# ひとまずは空欄以外の全てのPivotItemのVisibleをFalseする。
for pi in ptable.PivotFields("ID").PivotItems():
pi.Visible = False if pi.Name != "(blank)" else True
# 必要なPivotItemのVisibleをTrueにする。
ptable.PivotFields("ID").PivotItems("21").Visible = True
ptable.PivotFields("ID").PivotItems("22").Visible = True
ptable.PivotFields("ID").PivotItems("23").Visible = True
# 空欄のPivotItemが不要であれば空欄のPivotItemのVisibleをFalseにする。
ptable.PivotFields("ID").PivotItems("(blank)").Visible = False
print("press enter key to continue") # NO POST #
input() # NO POST #
# ------------------------------------------------------------------
# ピボットテーブルの設定
# ------------------------------------------------------------------
print("# ピボットテーブルのIDの複数のアイテムを設定 #")
print("# 指定のItemはTrue/指定以外のItemはFalse #")
ptable.PivotFields("ID").ClearAllFilters()
ptable.PivotFields("ID").EnableMultiplePageItems = True
for pi in ptable.PivotFields("ID").PivotItems():
pi.Visible = pi.Name in ["21", "22", "23", "29", "(blank)"]
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのIDの複数のアイテムを設定 #")
print("# 指定のItemはFalse/指定以外のItemはTrue #")
print("# TrueになるItemが0個になってしまうとError #")
ptable.PivotFields("ID").ClearAllFilters()
ptable.PivotFields("ID").EnableMultiplePageItems = True
for pi in ptable.PivotFields("ID").PivotItems():
pi.Visible = pi.Name not in ["21", "22", "23", "29", "(blank)"]
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのIDの複数のアイテムを設定 #")
print("# 指定のItemはTrue/指定以外のItemは変更しない #")
# ptable.PivotFields("ID").ClearAllFilters()
# ptable.PivotFields("ID").EnableMultiplePageItems = True
for pi in ptable.PivotFields("ID").PivotItems():
if pi.Name in ["21", "22"]:
pi.Visible = True
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのIDの複数のアイテムを設定 #")
print("# 指定のItemはFalse/指定以外のItemは変更しない #")
print("# TrueになるItemが0個になってしまうとError #")
# ptable.PivotFields("ID").ClearAllFilters()
# ptable.PivotFields("ID").EnableMultiplePageItems = True
for pi in ptable.PivotFields("ID").PivotItems():
if pi.Name in ["25", "26"]:
pi.Visible = False
print("press enter key to continue") # NO POST #
input() # NO POST #
# ------------------------------------------------------------------
# ピボットテーブルの設定
# ------------------------------------------------------------------
print("# 上記までの処理方法は #")
print("# ピボットテーブルがループ毎に更新されかねない為 #")
print("# Item数やData量が多い場合は処理に時間が掛かる… #")
print("# コンソールに進捗を出力して気を紛らす場合は以下 #")
print("# ピボットテーブルのIDの複数のアイテムを設定 #")
print("# 指定のItemはTrue/指定以外のItemはFalse #")
ptable.PivotFields("ID").ClearAllFilters()
ptable.PivotFields("ID").EnableMultiplePageItems = True
for i, pi in enumerate(lst := ptable.PivotFields("ID").PivotItems()):
pi.Visible = pi.Name in ["21", "22", "23", "29", "(blank)"]
print(f"{i+1:04}/{len(lst):04}")
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのIDの複数のアイテムを設定 #")
print("# 指定のItemはFalse/指定以外のItemはTrue #")
print("# TrueになるItemが0個になってしまうとError #")
ptable.PivotFields("ID").ClearAllFilters()
ptable.PivotFields("ID").EnableMultiplePageItems = True
for i, pi in enumerate(lst := ptable.PivotFields("ID").PivotItems()):
pi.Visible = pi.Name not in ["21", "22", "23", "29", "(blank)"]
print(f"{i+1:04}/{len(lst):04}")
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのIDの複数のアイテムを設定 #")
print("# 指定のItemはTrue/指定以外のItemは変更しない #")
# ptable.PivotFields("ID").ClearAllFilters()
# ptable.PivotFields("ID").EnableMultiplePageItems = True
for i, pi in enumerate(lst := ptable.PivotFields("ID").PivotItems()):
if pi.Name in ["21", "22"]:
pi.Visible = True
print(f"{i+1:04}/{len(lst):04}")
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのIDの複数のアイテムを設定 #")
print("# 指定のItemはFalse/指定以外のItemは変更しない #")
print("# TrueになるItemが0個になってしまうとError #")
# ptable.PivotFields("ID").ClearAllFilters()
# ptable.PivotFields("ID").EnableMultiplePageItems = True
for i, pi in enumerate(lst := ptable.PivotFields("ID").PivotItems()):
if pi.Name in ["25", "26"]:
pi.Visible = False
print(f"{i+1:04}/{len(lst):04}")
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのIDのフィルターの解除 #")
ptable.PivotFields("ID").ClearAllFilters()
print("press enter key to continue") # NO POST #
input() # NO POST #
# ------------------------------------------------------------------
# ピボットテーブルの設定とデータソースの変更
# ------------------------------------------------------------------
print("# 上記までの処理方法は #")
print("# ピボットテーブルがループ毎に更新されかねない為 #")
print("# Item数やData量が多い場合は処理に時間が掛かる… #")
print("# ピボットテーブルのみの解決方法が思い付かない為 #")
print("# データソースにヘルパー列を追加して対応する方法 #")
def PivotFieldSetVisibleItemsListWithDynamicArrayFormula(pf, visible, primary=None, prefix="", suffix="Visible"):
pt = pf.Parent
pc = pt.PivotCache()
ws = pt.Parent
wb = ws.Parent
ap = ws.Application
sd = ap.ConvertFormula(pc.SourceData, xlR1C1, xlA1, xlRelative)
rg = ap.Evaluate(sd)
SourceDataRange = rg
print("# 数式を作成 #")
rg = SourceDataRange
rg = rg.find(pf.Name, rg.GetResize(1, 1), xlValues, xlWhole, xlByRows, xlNext, True)
rg = rg.EntireColumn
covered = rg.GetAddress(False, False)
rg = SourceDataRange
rg = rg.GetResize(1, 1)
rg = rg.EntireColumn
primary = primary or rg.GetAddress(False, False)
formula = f'=SWITCH(FILTER({covered},NOT(ISBLANK({primary}))),"{pf.Name}","{prefix}{pf.Name}{suffix}",'
formula += "".join([(f"{v},1," if type(v) is not str else f'"{v}",1,') for v in visible])
formula += "0)"
print("# 数式を入力 #")
rg = SourceDataRange
cc = rg.Columns.Count
rg = rg.GetResize(1, 1)
rg = rg.GetOffset(0, cc)
rg.Formula2 = formula
print("# ピボットテーブルのキャッシュを変更 #")
rg = SourceDataRange
rc = rg.Rows.Count
cc = rg.Columns.Count
rg = rg.GetResize(rc, cc + 1)
pc = wb.PivotCaches().Create(SourceType=xlDatabase, SourceData=rg)
pt.ChangePivotCache(pc)
print("# ピボットテーブルのフィルターを追加 #")
pt.PivotFields(f"{prefix}{pf.Name}{suffix}").Orientation = xlPageField
pt.PivotFields(f"{prefix}{pf.Name}{suffix}").Position = 1
print("# ピボットテーブルのフィルターを設定 #")
pt.PivotFields(f"{prefix}{pf.Name}{suffix}").ClearAllFilters()
pt.PivotFields(f"{prefix}{pf.Name}{suffix}").CurrentPage = 1
return pt, pt.PivotCache()
print("# データソースにヘルパー列として動的配列数式追加 #")
print("# ピボットテーブルのフィルターを動的配列数式の結果が1で表示 #")
print("# 指定のItemは1/指定以外のItemは0 #")
print("# 指定のItemに(blank)の指定は不可 #")
print("# 動的配列数式動作環境Excel2021~ #")
pf = ptable.PivotFields("ID")
visible = [21, 22, 23, 29]
# primary = "A:A" # データソースの空欄の無い列を指定。省略すると一番左側の列を使用。
# ptable, pcache = PivotFieldSetVisibleItemsListWithDynamicArrayFormula(pf, visible, primary)
ptable, pcache = PivotFieldSetVisibleItemsListWithDynamicArrayFormula(pf, visible)
ptable.PivotFields("IDVisible").Position = 2
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのフィルターを解除 #")
ptable.PivotFields("IDVisible").ClearAllFilters()
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# データソースにヘルパー列として動的配列数式追加 #")
print("# ピボットテーブルのフィルターを動的配列数式の結果が1で表示 #")
print("# 指定のItemは1/指定以外のItemは0 #")
print("# 指定のItemに(blank)の指定は不可 #")
print("# 動的配列数式動作環境Excel2021~ #")
pf = ptable.PivotFields("Meta")
visible = ["hoge", "piyo"]
# primary = "A:A" # データソースの空欄の無い列を指定。省略すると一番左側の列を使用。
# ptable, pcache = PivotFieldSetVisibleItemsListWithDynamicArrayFormula(pf, visible, primary)
ptable, pcache = PivotFieldSetVisibleItemsListWithDynamicArrayFormula(pf, visible)
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのフィルターを解除 #")
ptable.PivotFields("MetaVisible").ClearAllFilters()
print("press enter key to continue") # NO POST #
input() # NO POST #
# ------------------------------------------------------------------
# ピボットテーブルの設定
# ------------------------------------------------------------------
print("# ピボットテーブルのTypeの順序を昇順に設定 #")
ptable.PivotFields("Type").AutoSort(Order=xlAscending, Field="Type")
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのTypeを0より大きいに設定 #")
ptable.PivotFields("Type").PivotFilters.Add2(Type=xlCaptionIsGreaterThan, DataField=None, Value1=0)
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのTypeを合計が10より大きいに設定 #")
ptable.PivotFields("Type").PivotFilters.Add2(Type=xlValueIsGreaterThan, DataField=ptable.PivotFields("SumCount"), Value1=10)
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのTypeの2222を含まないよう設定 #")
ptable.PivotFields("Type").PivotItems("2222").Visible = False
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのTypeのフィルターの解除 #")
ptable.PivotFields("Type").ClearAllFilters()
print("press enter key to continue") # NO POST #
input() # NO POST #
# ------------------------------------------------------------------
# ピボットテーブルの設定
# ------------------------------------------------------------------
print("# ピボットテーブルのDateの期間を設定 #")
ptable.PivotFields("Date").PivotFilters.Add2(Type=xlDateBetween, DataField=None, Value1="1900/1/1", Value2="3000/1/1")
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのDateに自動的にグループ化を設定 #")
ptable.PivotFields("Date").AutoGroup()
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのDateのグループ解除 #")
drange = ptable.PivotFields("Date").DataRange
drange.Cells(1, 1).Ungroup()
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのDateに年と月のグループ化を設定 #")
drange = ptable.PivotFields("Date").DataRange
drange.Cells(1, 1).Group(Start=True, End=True, By=None, Periods=tuple([False, False, False, False, True, False, True]))
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのDateの年の小計を非表示 #")
ptable.PivotFields("年 (Date)").Subtotals = tuple(False for _ in range(12))
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのDateの年を非表示 #")
ptable.PivotFields("年 (Date)").Orientation = xlHidden
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのDateのグループ解除 #")
drange.Cells(1, 1).Ungroup()
print("press enter key to continue") # NO POST #
input() # NO POST #
# ------------------------------------------------------------------
# ピボットテーブルのスライサー
# ------------------------------------------------------------------
print("# ピボットテーブルのスライサーのキャッシュの作成 #")
scache1 = wb.SlicerCaches.Add2(Source=ptable, SourceField="Type")
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーの作成 #")
slicer1 = scache1.Slicers.Add(SlicerDestination=ws)
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーのキャッシュのフィルターの解除 #")
scache1.ClearAllFilters()
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーのキャッシュの設定 #")
scache1.SlicerItems("2222").Selected = False
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーの順序を昇順に設定 #")
scache1.SortItems = xlSlicerSortAscending
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーの各種設定 #")
slicer1.Name = "Type"
slicer1.Caption = "Type"
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーの位置設定 #")
slicer1.Top = 0
slicer1.Left = 500
slicer1.Width = 100
slicer1.Height = 100
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーの位置設定 #")
slicer1.Top = ws.Range("A20").Top
slicer1.Left = ws.Range("A20").Left
slicer1.Width = ws.Range("D30").Left - ws.Range("A20").Left
slicer1.Height = ws.Range("D30").Top - ws.Range("A20").Top
print("press enter key to continue") # NO POST #
input() # NO POST #
# ------------------------------------------------------------------
# ピボットテーブルのスライサー
# ------------------------------------------------------------------
print("# ピボットテーブルのスライサーのキャッシュの作成 #")
scache2 = wb.SlicerCaches.Add2(Source=ptable, SourceField="Name")
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーの作成 #")
slicer2 = scache2.Slicers.Add(SlicerDestination=ws)
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーのキャッシュのフィルターの解除 #")
scache2.ClearAllFilters()
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーのキャッシュの設定 #")
scache2.SlicerItems("nico").Selected = False
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーの順序を降順に設定 #")
scache2.SortItems = xlSlicerSortDescending
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーの各種設定 #")
slicer2.Name = "Name"
slicer2.Caption = "Name"
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーの位置設定 #")
slicer2.Top = 0
slicer2.Left = 600
slicer2.Width = 100
slicer2.Height = 100
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーの位置設定 #")
slicer2.Top = ws.Range("D20").Top
slicer2.Left = ws.Range("D20").Left
slicer2.Width = ws.Range("G30").Left - ws.Range("D20").Left
slicer2.Height = ws.Range("G30").Top - ws.Range("D20").Top
print("press enter key to continue") # NO POST #
input() # NO POST #
# ------------------------------------------------------------------
# ピボットテーブルのタイムライン
# ------------------------------------------------------------------
print("# ピボットテーブルのタイムラインのスライサーのキャッシュの作成 #")
scache3 = wb.SlicerCaches.Add2(Source=ptable, SourceField="Date", Name="NativeTimeline_Date", SlicerCacheType=xlTimeline)
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのタイムラインのスライサーの作成 #")
slicer3 = scache3.Slicers.Add(SlicerDestination=ws)
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのタイムラインのスライサーのキャッシュのフィルターの解除 #")
scache3.ClearAllFilters()
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのタイムラインのスライサーのキャッシュの設定 #")
scache3.TimelineState.SetFilterDateRange(StartDate="2020/1/1", EndDate="2030/1/1")
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのタイムラインのスライサーのレベルの設定 #")
slicer3.TimelineViewState.Level = xlTimelineLevelMonths
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのタイムラインのスライサーの各種設定 #")
slicer3.Name = "Date"
slicer3.Caption = "Date"
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーの位置設定 #")
slicer3.Top = 0
slicer3.Left = 700
slicer3.Width = 300
slicer3.Height = 100
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# ピボットテーブルのスライサーの位置設定 #")
slicer3.Top = ws.Range("A30").Top
slicer3.Left = ws.Range("A30").Left
slicer3.Width = ws.Range("G40").Left - ws.Range("A30").Left
slicer3.Height = ws.Range("G40").Top - ws.Range("A30").Top
print("press enter key to continue") # NO POST #
input() # NO POST #
# ------------------------------------------------------------------
# ピボットテーブルの更新
# ------------------------------------------------------------------
print("# 指定のピボットテーブルの更新 #")
pcache.Refresh()
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# 指定のピボットテーブルの更新 #")
ptable.RefreshTable()
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# 指定のピボットテーブルの更新 #")
ptable.Update()
print("press enter key to continue") # NO POST #
input() # NO POST #
print("# 全部のピボットテーブルの更新 #")
wb.RefreshAll()
print("press enter key to continue") # NO POST #
input() # NO POST #
# ------------------------------------------------------------------
print("# 指定したシートを選択 #")
ws.Activate()
# print("press enter key to continue") # NO POST #
# input() # NO POST #
print("# 指定したシートを選択 #")
ws.Select()
# print("press enter key to continue") # NO POST #
# input() # NO POST #
print("# A1セルを選択 #")
ws.Range("A1").Select()
# print("press enter key to continue") # NO POST #
# input() # NO POST #
# ------------------------------------------------------------------
print("# ブックを保存せずにクローズ #")
wb.Close(False)
# print("press enter key to continue") # NO POST #
# input() # NO POST #
# ------------------------------------------------------------------
print("# Excel終了 #")
xlApp.Quit()
print("press enter key to continue") # NO POST #
input() # NO POST #
# ------------------------------------------------------------------
# NO POST #
print("press enter key to exit") # NO POST #
input() # NO POST #
if __name__ == "__main__":
main()
@SathishKies
Copy link

This was really a helpful guide for me, I'm working on a personal project and just getting started with pywin32 it was hard finding the enums for the excel objects and stumbled upon this and have to say it's a god send. I do have a doubt I'm trying to get the fieldnames from the pivot table and I'm not getting the desired result can you point me in the right direction?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment