Pythonを使って、MicrosoftのExcelを動かす方法を紹介します。 具体的には、
という作業を行います。
私自身、普段Excelで作業することは無いので簡単な例だけです。
それとVisual Basicもほとんど使わないので、
プロパティやメソッドの意味等、よく理解していません。
※:Python で Excel のグラフ作成 (Windows編)の解説ページも作りました
まず、Excelをオブジェクトとして作る必要があります。
import win32com.client
xlApp = win32com.client.Dispatch("Excel.Application")
xlApp.Visible = 1
xlApp.Workbooks.Add()
xlSheet = xlApp.Workbooks(1).Sheets(1)
1、2行目は呪文みたいなものです。
これで「xlApp」が、Excelのオブジェクトの元になります。
実際に画面に表示させて、ワークブック(シート)を表示させるには、3、4行目が必要です。
5行目で最初のシートを「xlSheet」オブジェクトにしています。
なお、このスクリプトを繰り返すと、2回目以降はシートが表示されないようです。
いきなりですが、終了させてみましょう。
xlApp.Quit()
これでExcelは終了します。
以後、実際にいじってみるために、まず Python を終了して、 上の5行のスクリプトを「PythonWin」のエディタで開いて実行します。 Excelのシートが開いたら、2、3、4行目をコメントにしておきます。
import win32com.client
# xlApp = win32com.client.Dispatch("Excel.Application")
# xlApp.Visible = 1
# xlApp.Workbooks.Add()
xlSheet = xlApp.Workbooks(1).Sheets(1)
この下にスクリプト書いて、何回も繰り返し試してみることが出来ます。 以下のスクリプト例では、特に断らない限り、上の行は省略します。
セルの操作の例をいくつか紹介します。
eggCell = xlSheet.Cells(1,1) eggCell.Value = "A" eggCell.Font.Size = 18 eggCell.Font.Bold = True
セルの指定は(行, 列)の数値だけしか出来ないようです。
Cells("A1") や Cells("R1C1") とかではエラーになります。
「Value」「Font.Size」などは文字列・数値をそのまま代入できます。
太文字にするのは「Font.Bold」を True か False、あるいは数値の1, 0で指定します。
この辺は、実際にマクロを記録して、どんなプロパティ・メソッドを使っているか調べて、
ヘルプのVisual Basic レファレンスで詳しい設定を調べます。
問題は、次のようなわかりにくいプロパティです。
eggCell.HorizontalAlignment = 4
これは、セルの中の配置を右揃えにします。
Visual Basic レファレンスでは「HorizontalAlignment」の値として
「xlHAlignCenter, xlHAlignDistributed, xlHAlignJustify, xlHAlignLeft, xlHAlignRight」が使用できる
とありますが、Python のスクリプトでは、これらの文字列を代入するとエラーになります。
上の例のように整数を使わなければいけません。
しかも、どの整数がどの設定に対応してるかは「やってみないとわからない」のです
(しかも設定項目がレファレンスに書いてあるのより多い!)。
これを解決するのに半日以上かかりました・・・(え?、たいしたことないって?)。
具体的な対応は下の表のようになります。
| HorizontalAlignmentの数値 | 位置 | Visual Basic での名前 |
|---|---|---|
| 1 | 標準 | xlHAlignGeneral |
| 2 | 左詰め | xlHAlignLeft |
| 3 | 中央揃え | xlHAlignCenter |
| 4 | 右詰め | xlHAlignRight |
| 5 | 繰り返し | xlHAlignFill |
| 6 | 両端揃え | xlHAlignJustify |
| 7 | 選択範囲内で中央 | xlHAlignCenterAcrossSelection |
| 8 | 均等割り付け | xlHAlignDistributed |
範囲の指定は、A1、F5 などで指定します。
xlSheet.Range("A1:C1").Value = ("AA", "BA", "CA")
値の指定は、タプルかリストで行います。上の例は一つの行だけですが、 複数行に値を入れるには次のように タプルのタプル(リストでも可)にします。
xlSheet.Range("A1:C3").Value = (("AA", "BA", "CA"), ("AB", "BB", "CB"), ("AC", "BC", "CC"))
左辺の範囲の指定と右辺の配列の構造が一致しない場合は・・・どうなるか自分で試してみてください。
次に、範囲に罫線を描いてみましょう。 これが実はセルのところで書いた「やってみないとわからない」プロパティです。
xlSheet.Range("D3:F6").Borders.Weight = 3
これで、範囲の境界と内部に罫線が描かれます。「3」は罫線の太さ「xlMedium」になります。
範囲の境界だけに罫線を描きたいという場合は「Borders(1)」のように数値で指定します。
この数値で何が変わるのか「やってみないとわからない」です。
実際のところ、下の表のようになります。
| Borders(#) の数値 | 実際の罫線 | Visual Basic での名前 |
|---|---|---|
| 1 | すべてのセルの左辺 | ? |
| 2 | すべてのセルの右辺 | ? |
| 3 | すべてのセルの上辺 | ? |
| 4 | すべてのセルの下辺 | ? |
| 5 | すべてのセルの右下がり斜線 | xlDiagonalDown |
| 6 | すべてのセルの右上がり斜線 | xlDiagonalUp |
| 7 | 範囲の境界の左辺 | xlEdgeLeft |
| 8 | 範囲の境界の上辺 | xlEdgeTop |
| 9 | 範囲の境界の下辺 | xlEdgeBottom |
| 10 | 範囲の境界の右辺 | xlEdgeRight |
| 11 | 範囲の内部の垂直線 | xlInsideVertical |
| 12 | 範囲の内部の水平線 | xlInsideHorizontal |
したがって、例えば、
xlSheet.Range("D3:F6").Borders(8).Weight = 4
は、範囲(D3:F6)の境界の上辺に、太い(xlThick)罫線を描きます。
ファイルの保存は、次のようにします。Filenameの部分に保存したいパスを書きます。
xlApp.Workbooks(1).SaveAs(Filename = "D:\Excel\File.xls")
最後に簡単な例を作ってみます。
import win32com.client
MyData = (('A',3),('B',6),('C',1)) #元データ
LenData = len(MyData)
xlApp = win32com.client.Dispatch("Excel.Application")
xlApp.Visible = 1
xlApp.Workbooks.Add()
xlSheet = xlApp.Workbooks(1).Sheets(1)
for i in range(LenData):
xlSheet.Cells(i+1,1).value = MyData[i][0]
xlSheet.Cells(i+1,2).value = MyData[i][1]
SumCell = xlSheet.Cells(LenData+1,2)
SumCell.Value = "=SUM(B1:B%d)" % LenData #合計欄の数式
AllRegion = SumCell.CurrentRegion #セルを含む表全体の選択
AllRegion.Borders.Weight = 2
xlSheet.Range("A%d:B%d" % (LenData, LenData)).Borders(9).Weight = 4
xlApp.Workbooks(1).SaveAs(Filename = "D:\Excel\PyExcel.xls")
xlApp.Quit()
MyData のデータを表にして、合計欄をつくり、全体を罫線で囲んでます。
LenData はデータのリストの項目数です。
これが表の行数の基本になり、後で何回か使うので変数に入れておきます。
for からのループでデータを入力していきます。
ここで注意することは、Pythonでは番号は0から始まりますが、Excelでは1からになるので、
i+1 と 1を加えてそろえてます。
この例ではデータは2列だけですが、多い場合は列についてもループさせたほうが良いでしょう。
表の最後に合計欄をつくります。その行位置は「データの行数+1」つまり、LenData+1
になります。
また、合計欄の数式は「SUM(B1:B{行数})」なので、Pythonの文字列フォーマットを使って
"=SUM(B1:B%d)" % LenData とします。
実際のセルの値(数式)は「=SUM(B1:B3)」になります。
次に、表全体の範囲 AllRegion を得るために、便利な関数(メソッド)CurrentRegion を使ってます。
これは「そのセル(ここではSumCell)を含む表全体の範囲を得る」ものです。
こうして表全体に罫線を描きます。ついでに元データと合計欄の間に太めの罫線を引いてます。
最後にファイルに保存して終了です。
以上が初歩的な操作の解説です。私自身に必要な操作は上に書いたことで十分です。 さらに高度な表計算・グラフなど使う場合は、また別の問題が出てくるかもしれませんが、 上のことを取っ掛かりにして研究すれば、なんとか出来ると思います。