エクセル差分抽出ツール(ii-excel-diff)で、オリジナルのエクセルと同じセル幅で出力エクセルを設定しようとしても、うまくいっていないファイルがありました
openpyxl あるいは エクセル のクセのようなものと思われるため、その内容について記録しておくこととします
列幅がオリジナルと異なってしまう現象
列幅をオリジナルと同じ値で設定して、見た目を同じにしたいので、以下のようなコードを書いていました
target_ws.column_dimensions[get_column_letter(col + col_num)].width = source_ws.column_dimensions[get_column_letter(col_num)].widthこれでほとんどのエクセルで問題なく動作していましたが、一部のエクセルファイルのときだけ、
下図のように オリジナル とは列幅が異なる結果となっていました

原因の推測
1.コーディングミス:右辺の変数の参照先の間違い
代入するもの自体が間違っていたら、そらもうおかしいよね・・・
配列を使っているので、要素番号が間違っているのではないか?と確認するも問題なし
まぁ、当然ですよね・・・
一部のファイルだけ列幅がコピーされていないので・・・
実際に ***.width の値がどうなっているか?を見てみると意外な数値が並んでいました
2.0
13.0
13.0
13.0
: 以下略見た目上の列幅のサイズは全列で 2.1
1列目(上図の1行目)の値こそは近しい数値ではあるものの、他はすべて 13.0 で異なる数値となっています
いよいよ要素番号以外で何か参照先が異なるのか?と思い、コードを見直すも問題なし
2.設計ミス:右辺を参照する条件の間違い
オリジナルのエクセルは Ctrl+A で全セルを選択の上、列幅を変更していたため、1つ前の結果もあり、***.width を参照する前に、その値を参照すべきか否かの条件があるのだろうと推測をしました
結果、***.width = None のときは、列幅にシートのデフォルト値(source_ws.sheet_format.defaultColWidth)を使うという情報にいきつきました
しかし、13.0 が入っているんだよね・・・
ChatGPT や google 検索で調べるも、これといった情報もなく、openpyxl では、この課題は解決できないものと判断しました
3.課題まとめ
ライブラリ仕様とでもいいましょうか、普通には解決しないことがわかりました
結果、整理しますと下記の課題となります
Ctrl+A などで複数列を選択した状態で複数列の列幅を変えると
***.width の値は変更されず、シートデフォルト値の値が変更される結果、***.width に値は入っているが、***.width を信頼してはいけないケースが存在する
***.width を信頼してよいか、わるいかを判断する情報は提供されていない
対策の検討
1.別のライブラリで列幅を調べる
ChatGPT によると win32com あるいは xlwings を使うことで、列幅を取得できるような解決策を示してくれました
openpyxl と似たようなコードにしか見えないが・・・
2.仮説:一番多い列幅値を使う列の信頼性が怪しいからその列の列幅はデフォルト値を入れたらいいのではないか
Ctrl+A で複数列を選択して、列幅を変更することによって ***.width には値が入らず、None でもなく、デフォルト値に値が入るということならば、
もしかして、ほとんどの列は 「同じ値が入っている」 のではないかと思いました
実際、13.0 が入っている訳ですから・・・
対策の実施・結果
対策は 検討2 の内容をベースに対策をすることとする
検討1は openpyxl と同じようなコードで同じようなことをしているだけなので、本当に改善するのか怪しいなと思ったことと、ライブラリを増やすことで処理速度や exe の肥大化が嫌だったので、試すことなく採用しないと判断しました
検討2はしきい値(どのくらい同じ値がでてきたら、デフォルト値を採用するか)を決めるのに難しさを感じますが、基本的には問題なく、試してみる価値があると感じ、
検討2の内容をベースに対策することとしました
細かくは書かないですが、一番発生頻度の高い列幅値で かつ 発生確率が xx 以上(企業秘密w)の場合に、デフォルト値を採用するようにしました
結果:オリジナルと同じ列幅で設定ができました

0 件のコメント:
コメントを投稿