← ポチっていただけると嬉しいです
Python

openpyxlで実現できずwin32comになる

VBAでやってる処理をPythonに置き換えてます。

とある表を取り込んで、データ処理をして既存のエクセルに追記していくって感じの処理。

まずは定番のopenpyxlを使ってみました。

結論を言うと私の用途には使えなかった。

まず、xlsmファイルが開けない。
ってことはVBAと両立が出来ないということ。

まぁこれはVBAで行ってる処理を全部Pythonで置き換えられたらxlsxにしても問題ないので解決はできるはず。

どうしてもダメだったのが、
数式が書いてあるセルから読み出す場合に、数式として読み出すのか、値として読み出すのかが
openpyxl.load_workbookの data_only の設定で決める必要があるということ。

ブックを読み出す時に決める必要があるということは、エクセルを開いた後に、式を読むか値を読むかは決められない。

数値を読んで判断して数式を書き込むってことが出来ない。

たとえばA2のセルにA1+1が数式で入っていて値としては、2021/1/2 となってたとする。
で、今日の日付のデータが無かったらA3に日付を、B3に値をに書き込むとした場合、
A3には2021/1/3を書くんじゃなくて、A2+1と書きたい。

処理そのものは可能。
ブックを開く際にdata_only=Trueで開いて判断して一旦閉じて
次にdata_only=Faleで開いてA3にTranslatorを使ってA2からのコピーを書き込む
という二度手間になってしまうけどできることはできる。全然美しくないけど。

同じ処理がVBAの場合、セルのHasFormulaというプロパティでセルが数式かどうか判断ができるし、.Formulaで数式として、.Valueで値として読める。
楽さがぜんぜん違う。

また、数式のコピーも
A2のA1+1をA3にコピーする際にA2+1と参照先を移動してほしい。

translatorを使えばopenpyxlでもこれはできるんだけど書くのがちょい面倒
VBAの場合はFormulaR1C1プロパティで代入するだけでOK
Cells(last + 1, 1).FormulaR1C1 = Cells(last, 1).FormulaR1C1

というわけで、すべてPythonで処理し、表示だけExcelならopenpyxlでいいのかもしれないけど、データ取り込みと前処理だけPythonにまかせてエクセルの表計算自体の機能は使いたいって用途には厳しいんじゃないかと思ったわけです。

 

というわけで結局 win32com に落ち着きました。
一応やりたいことは一通りできました。速度もかなりアップ。

ただ、win32comだとWindowsだけってことですよね。
Macだとwin32com使えないんでしょう。ここがちょっとネックです。

 

まだまだpython初心者なのでこんな知識ですが、達人ならopenpyxlでもスマートにできるのかもしれませんけどね。

 

コメント

タイトルとURLをコピーしました