【Python】エクセル:ソートSort(昇順・降順)する方法(win32com、openpyxl)
2021.02.17 /
本記事ではPythonでエクセル操作を行い、ソートSort(昇順・降順)する方法について解説していきます。
エクセルのセル範囲内をソートしてデータを並べ替えることは、エクセル作業をするうえでよく行います。
エクセルのフィルター機能やVBAを使えば簡単にソートをすることができます。
Pythonでも同じように簡単にソートすることができます。
win32comを使ったエクセルのソート(昇順・降順)方法について見ていきましょう。
本記事を通して以下の知識を学べます。
- win32comの使い方
- win32comでエクセルをソート(昇順・降順)する方法
- openpyxlでフィルターをエクセルに付ける方法
Pythonでソートする方法
Pythonにはopenpyxlやwin32comといったエクセル操作のライブラリが用意されています。
Pythonでエクセルデータをソートするにはwin32comを使用します。
win32comでマクロVBAを使用することができます。
win32comを使う上での注意点として、OSがWindowsかつMicrosoft製品であるExcelがインストールされている必要があります。
win32comの詳しい使い方は以下記事をご参照ください。
【Python】エクセル操作:win32comを通してマクロVBAを使用する方法
openpyxlではエクセルのソート(昇順・降順)を自動ですることはできません。
しかしフィルターをエクセルに付けることは可能です。
openpyxlの基本的な使い方は以下記事をご参照ください。
【Python】openpyxl:基本的なエクセル操作方法を徹底解説
以下ではこれらの方法について解説します。
win32comでのソート(昇順・降順)方法
win32comの準備
win32comは標準ライブラリではないので、pipによるインストールが必要です。
pip install pywin32
Pythonスクリプトで使用するためにスクリプトの先頭でwin32comをインポートします。
import win32com.client
対象のエクセルファイルを開く
まずはエクセル本体を起動します。
excel = win32com.client.Dispatch("Excel.Application")
今回は「エクセルの上書きをしますか」といった警告表示をなくすためにDisplayAlertsをFalseにします。
excel.DisplayAlerts = False
次に対象となるエクセルファイルを開きます。
wb = excel.Workbooks.Open("C:\OFFICE54\OFFICE54.xlsx")
ここではOFFICE54.xlsxという次のようなエクセルを対象とします。
ワークシートを開く
次に対象のワークシートを開きます。
ws = wb.Worksheets(1)
ここでは左から1番目のワークシートを開いています。
Sortで使用する変数に数値を代入
VBAでエクセルの並び替えにはSortメソッドを使用しますよね。
Rangeオブジェクト.Sort Key1:=キー, Order1:=並び替えのルール ,Header:=先頭行見出しの指定
win32comを使用することでPythonでもVBAのコマンドが使用できます。
こういったVBA専用の定数を使用する場合は、その定数の数値を代入しておく必要があります。
以下にSortで使用する定数の一覧を記します。
定数 | 数値 |
---|---|
xlAscending | 1 |
xlDescending | 2 |
xlManual | -4135 |
xlGuess | 0 |
xlYes | 1 |
xlNo | 2 |
xlSortColumns | 1 |
xlSortRows | 2 |
xlPinYin | 1 |
xlStroke | 2 |
xlSortNormal | 0 |
xlSortTextAsNumbers | 1 |
Pythonでwin32comを使用し、Sortメソッドを使用する場合は、各VBA定数に上記数値を代入してから使用してください。
# Sortで使用する変数に数値を代入
xlAscending = 1
xlDescendig = 2
xlYes = 1
ソート(昇順・降順)を行う
Pythonのwin32comを使用してソートする場合、次のように記述します。
ws.範囲指定.Sort(Key1=ws.並び替えのキー, Order1=並び替えのルール, Header=先頭行見出しの指定)
エクセルのA列とB列を範囲指定し、昇順、先頭行をタイトル指定すると次のように記述します。
ws.Columns("A:B").Sort(Key1=ws.Range("B2"), Order1=xlAscending, Header=xlYes)
サンプルプログラム
上記をふまえてOFFICE54.xlsxをB列をキーとして昇順するサンプルプログラムを以下に記します。
import win32com.client
# エクセルの起動
excel = win32com.client.Dispatch("Excel.Application")
excel.DisplayAlerts = False
# 既存のエクセルを開く
wb = excel.Workbooks.Open("C:\OFFICE54\OFFICE54.xlsx")
# ワークシートの指定
ws = wb.Worksheets(1)
ws.Activate()
# Sortで使用する変数に数値を代入
xlAscending = 1
xlDescendig = 2
xlYes = 1
ws.Columns("A:B").Sort(Key1=ws.Range("B2"), Order1=xlAscending, Header=xlYes)
wb.SaveAs("C:\OFFICE54\test.xlsx")
wb.Close()
このサンプルプログラムを起動すると次のようなエクセルが作成されます。
画像を見るとわかるように、タイトル行を含めて昇順してしまっています。
理由はわかりませんが、win32comのSortではxlYesを指定して先頭行見出しありにしても、先頭行を含めて昇順にしてしまいました。
タイトルを含んでしまうバグの解決
HeaderにxlYesを指定しても先頭行を含んでしまうので、範囲指定時に先頭行を含めない範囲を指定することで、この問題を回避することができます。
今回のOFFICE54.xlsxでは、セルA2からB列の最終行までを範囲指定すればいいということです。
最終行の取得方法については以下記事をご参照ください。
【Python】エクセル操作:最終行を取得する方法(win32com/End(xlUp))
サンプルプログラムでタイトル行を含めずにソート昇順するには、ソートの部分を以下のように記述します。
xlUp = -4162
lastrow = ws.Cells(ws.Rows.Count, 2).End(xlUp).Row
ws.Range(ws.Range("A2"), ws.Cells(lastrow, 2)).Sort(Key1=ws.Range("B2"), Order1=xlAscending, Header=xlYes)
このようにすることで正しく昇順にソートしたエクセルを得ることができました。
openpyxlでのフィルター追加
Pythonのopenpyxlでは昇順・降順をすることができません。
その代わりにフィルターを付けることができます。
ws.auto_filter.ref
OFFICE54.xlsxにフィルターを追加するサンプルプログラムを以下に記します。
import openpyxl
wb = openpyxl.load_workbook('C:\OFFICE54\OFFICE54.xlsx')
ws = wb.active
ws.auto_filter.ref = "A1:B11"
wb.save(r"C:\OFFICE54\test.xlsx")
まとめ
本記事「【Python】エクセル:ソートSort(昇順・降順)する方法(win32com、openpyxl)」はいかがでしたか。
win32comは使い方が難しいですが、使えるようになるとエクセルの自動化が楽になります。
ぜひwin32comとopenpyxlを組み合わせてエクセルの自動化プログラムを作ってみてください。