pywin32でExcelを操作してみる

# 目的
pywin32+Excelの調べものついでに少しだけ触って気がついたことをメモっておく
python 3.13.0 で試したところ以下の記載では動かないので(python 3.12系でも同じ)
修正版 [python 3.13+pywin32でExcelを操作してみる](https://qiita.com/tabizou/items/46dda9e5c9862b8d1de7) を参照してください
## 気が付いたこと
軽く検索したときに

```python
import win32com.client
xl = win32com.client.Dispatch("Excel.Application")
```
を見て以下を連想したんだけど

```vb
Dim myExcel As Object
Set myExcel = CreateObject("Excel.Application")
```
つまるところはそういうことなんですね
Object受けと同様なのでIntelliSenseが効かないのが残念！
Listが普通に使えるのはやはりうれしい


## パッケージの追加
[Installation](https://brian3johnson.github.io/pywin32/installation.html) より
<pre>
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
</pre>

## サンプルコード
VBAでCSVファイルを取り込んでWorksheetに書き込んでいるコードを書き直してみる
・対象データは[郵便番号検索](http://www.post.japanpost.jp/zipcode/)の17ISHIKA.CSV 
・コメントにもあるように、VBAで使用する定数はオブジェクトブラウザで確認できるようにExcel.Constantsに定義されている

```python
from win32com.client import constants as xlc
```
　の宣言により xlc.定数名で使用可能となる
・csv.readerで取り込んだ結果をそのままws.Range.Valueで書き込めるのは楽
※VBAだとRangeにVariantの配列に代入したデータを書き込む感じ
・よく使う機能以外(Worksheetの書式とかグラフの作成等)はマクロの記録で生成されたコードを修正することが多いから、定数の前に xlc. を追加することはひと手間だけど数が多いとなんとも言いがたい
※VBAのコード見慣れている人には、あまり違和感がない気がする

```python
# 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 =  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

# 以下の確認用にB2からWorksheetに記述している
print(ws.Range("B1").End(xlc.xlDown).Row)
print(ws.Range("B" + str(ws.Rows.Count)).End(xlc.xlUp).Row)
print(ws.Range("B3").End(xlc.xlToLeft).Column)
print(ws.Range("B3").End(xlc.xlToRight).Column)

# 保存する場合
# xl.Save()

# 今回は何もしない
xl.Quit()
```

# 参考にしたのは以下のサイト
[Python for Windows Extensions](https://brian3johnson.github.io/pywin32/index.html)
[mhammond/pywin32](https://www.moug.net/tech/acvba/0090016.html)
[Python pywin32(win32com) Excel 操作備忘録](https://qiita.com/feo52/items/150745ae0cc17cb5c866)
[PythonからExcelをwin32comで操作する](https://qiita.com/kumarstack55/items/9ae3432446afca06497f)
[第24回.エクセルを操作する（pywin32:win32com）](https://www.excel-ubara.com/python/python025.html)
[Excelを起動する（オートメーション）｜Access VBA](https://www.moug.net/tech/acvba/0090016.html)