目的
python 3.13,0 がリリースされて動作確認ということで
pywin32でExcelを操作してみる
を実行してみたらサンプルコードの xlc.xlLeft が参照不可をいうエラーメッセージが発生
これを解決するためには、パッケージの追加後の処理の項目にあるように
以下を実行する必要がある
PS C:\> python Python313\Lib\site-packages\win32com\client\makepy.py
既存のメモを修正するか迷ったのだけど、修正版を書くことにする
pywin32+Excelの調べものついでに少しだけ触って気がついたことをメモっておく
気が付いたこと
軽く検索したときに
import win32com.client
xl = win32com.client.Dispatch("Excel.Application")
を見て以下を連想したんだけど
Dim myExcel As Object
Set myExcel = CreateObject("Excel.Application")
つまるところはそういうことなんですね
Object受けと同様なのでIntelliSenseが効かないのが残念!
Listが普通に使えるのはやはりうれしい
パッケージの追加
Installation より
PS C:\> python -m pip install --upgrade pywin32
Collecting pywin32
Downloading pywin32-307-cp313-cp313-win_amd64.whl.metadata (8.3 kB)
Downloading pywin32-307-cp313-cp313-win_amd64.whl (6.5 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.5/6.5 MB 592.6 kB/s eta 0:00:00
Installing collected packages: pywin32
Successfully installed pywin32-307
パッケージの追加後の処理
以下を実行しないとサンプルコードの xlc.xlLeft が参照不可になる
※以前試した時は、この手順を実行しないで動作が確認できたと思うのだが(謎
※バージョン指定のインストールは不可?のようなので当時のバージョンで試せない。
※実行した場合はメモに残しているはずなのに・・
win32comで、makepyを使って COM(AcitveX)の定数をロードさせる手順について より
PS C:\> python \path\to\Python313\Lib\site-packages\win32com\client\makepy.py
を実行後に「Microsoft Excel ver Object Library」を選択後 OKボタンを押下する。
Generating to C:\path\to\Python313\Lib\site-packages\win32com\gen_py\00020813-0000-0000-C000-000000000046x0x1x9.py
Building definitions from type library...
Generating...
Importing module
サンプルコード
VBAでCSVファイルを取り込んでWorksheetに書き込んでいるコードを書き直してみる
・対象データは郵便番号検索の17ISHIKA.CSV
・コメントにもあるように、VBAで使用する定数はオブジェクトブラウザで確認できるようにExcel.Constantsに定義されている
from win32com.client import constants as xlc
の宣言により xlc.定数名で使用可能となる
・csv.readerで取り込んだ結果をそのままws.Range.Valueで書き込めるのは楽
※VBAだとRangeにVariantの配列に代入したデータを書き込む感じ
・よく使う機能以外(Worksheetの書式とかグラフの作成等)はマクロの記録で生成されたコードを修正することが多いから、定数の前に xlc. を追加することはひと手間だけど数が多いとなんとも言いがたい
・ユーザー定義型(Type)やWithステートメントは使用できないだろうけど、使えないと面倒な気も
ユーザー定義型(Type)はDBの読み書き前後に1レコード分づつReDim Preserve Type型の配列を追加 しながらデータまとめるんだけど、美しくない実装になりそうだ
Python的発想がもう少し強くなると考え方も違ってくるんだろうな
Withステートメントだめだと、コード見づらくなるし、省略形として短く定義するという事かな?
・スペルの大文字、小文字あたりは元々VBAは無視しているのでしょうがないと思うしかない気も
オブジェクトブラウザで見えるスペルが正しいスペルではと
# coding:utf-8
# Windows Add env PYTHONIOENCODING = UTF-8 & restart vscode
import win32com.client
# 定数はExcel.Constantsに定義されている
from win32com.client import constants as xlc
import os.path
import csv
xlfile = os.path.abspath(".") + "/samp.xlsx"
# csvfile = "17ISHIKA.CSV"
csvfile = os.path.abspath(".") + "/17ISHIKA.CSV"
addsheet = "KENCODE"
xl = win32com.client.Dispatch("Excel.Application")
xl.Visible = True
#ブックを開く
wb = xl.Workbooks.Open(xlfile)
# Worksheetの一覧を作成
lstws = []
for sh in wb.Worksheets:
lstws.insert(len(lstws), sh.Name)
# Worksheet一覧の表示
print(lstws)
# シート名[KENCODE]が存在すれば削除する
if addsheet in lstws:
xl.Application.DisplayAlerts = False
wb.Worksheets(addsheet).Delete()
xl.Application.DisplayAlerts = True
# ワークシートを追加後に名前を[KENCODE]とする
wb.Worksheets.Add()
xl.ActiveSheet.Name = addsheet
ws = wb.Worksheets(addsheet)
# 書式を先に付けた後にデータを貼り付ける
ws.Columns("A:Q").NumberFormatLocal = "@"
ws.Columns("A:Q").HorizontalAlignment = xlc.xlLeft
ws.Range("A1").Select()
rows = 1
with open(csvfile, newline='') as csvfile:
spamreader = csv.reader(csvfile, delimiter=',', quotechar='"')
for line in spamreader:
rows = rows + 1
# 書き込み対象Range単位で書式を付けても構わない
# 事前に定義してある領域からの書式のコピペはよくある(帳票用とか)
ws.Range(ws.Cells(rows, 1), ws.Cells(rows, 15)).NumberFormatLocal = "@"
ws.Range(ws.Cells(rows, 1), ws.Cells(rows, 15)).HorizontalAlignment = xlc.xlLeft
ws.Range(ws.Cells(rows, 2), ws.Cells(rows, 16)).Value = line
# 保存する場合
# xl.Save()
# 今回は何もしない
xl.Quit()
参考にしたのは以下のサイト
pywin32 · PyPI
Python for Windows Extensions
win32comで、makepyを使って COM(AcitveX)の定数をロードさせる手順について
mhammond/pywin32
Python pywin32(win32com) Excel 操作備忘録
PythonからExcelをwin32comで操作する
第24回.エクセルを操作する(pywin32:win32com)
Excelを起動する(オートメーション)|Access VBA