
2025-12-29
openpyxl で 保存が重い、出来上がったファイルが大きすぎると感じたとき
実際の失敗談からの展開になります
あれれ、何かおかしいぞ?
前々から ii-win-merge は少し重たくて、ii-diff は軽い!!
そんな印象を持っていたんですが
100 を超えるファイルを比較したときに、顕著にその差が見て取れて
ついに「おかしい!」と確信する事態となりました!!
重たい!という症状は
PC 全体の動きがもっさりしだすし
タスクマネージャを見ると メモリはフルに・・・
HDD も 14GB くらいの余裕があったのに
数百MB まで落ちている
そして、最終的にエラーで結果の出力ができない!ときた・・・
絶対、どこかでメモリリークのような開放漏れがあるんだろうと思いました
そこからは いろいろと トライ&エラー です orz
1回のトライ(ここを変えたらどうなる?ってお試し)に 3~5H かかりました
なんせ
100 を超えるファイルを比較して、処理が終わるころにエラーするもんだから
いちいち時間がかかる
そして、その間、PC が重くなるから、何もできなくなります
難航しました・・・
原因がわかったのは
ファイル数を 50個くらいに抑えて出力した結果を ii-diff の結果と比較しているときでした
そこに気づき着目しました!
ii-diff は 1,048,576行 (← 最新のエクセルで扱える最大行数)
ii-win-merge は 65,535行
行数が少ない ii-win-merge の方がファイルが大きくなるのはなぜ?と思う人もいるかもしれないですが・・・
ii-diff は値の入っている有効行が 差分表の最後の行(116行目)なのでエクセルの最終行に飛び
ii-win-merge は エクセルの最終行に飛ばないので、
差分表の後にも値の入っている行があって、その値の入っている最後の有効行に飛んだのだろう
そう解釈をしました (;^ω^)
よく見ると
実際
上図のようにグレー塗のセルが 65,535行まで続いていました
絶対これやん!!
そこを修正したら、さっくり軽くなり、約 7分 で結果出力できるようになりました ('ω')ノシ
シート当たりのデータ量が無駄に多かったんだもん
そら重いわな・・・
openpyxl は ワークブックの save() で時間がかかります
保持していたデータを xml にして、エクセルのファイル構成を作って
zip に圧縮するらしいです
データ量に比例して時間が増えますので、
小さなデータを扱っているつもりなのに、とても時間がかかるときは
私のように
意図せず広い範囲のセルを使っていないか、ご確認くださいませ 🙇♂️🙇♂️🙇♂️
2025-12-26
相対パス指定のショートカットを作成する方法
Windows でショートカットを作成すると絶対パスで本体を示すショートカットが作成されます ('ω')
会社生活を長くやっていると
・サーバーが変わりました
・旧サーバーから新サーバーでファイル・フォルダ構成そのままでコピーされる
ってことがときどき起こりえます
このとき、サーバーに置かれていたショートカットがリンク切れを起こして困ってしまいます
あらかじめ、絶対パスではない、相対パスのショートカットを配置しておけば、困ることもないのかな?と
相対パスでショートカットを作成できないかを調べてみた ![]()
ChatGPT 調べですが、Windows は標準では相対パスを推奨していないみたいで裏技的な技法らしいのですが、
リンクのプロパティからリンク先を以下のように指定したらよいらしいです ('ω')ノシ
%windir%\explorer.exe ..\ii-create-shortcut\icon.ico
実際、これをやろうとすると・・・ 以下のように、まぁまぁの手数が必要で かつ 相対パスを作り上げるのが面倒です
1. ショートカットを作成する(本体ファイルを右クリック → ショートカットの作成) ※Win11 なら右クリックの後もう1手が必要
2. ショートカットを適切なフォルダに移動させる
3. 相対パスの文字列を作成する
4. ショートカットのリンク先を変更する(ショートカットを右クリック → プロパティ → リンク先欄の修正)
ということで、
相対パス指定のショートカットを作成するアプリを作ってみました!! ('ω')ノシ
こちら になります
どうぞお試しくださいませ
2025-12-18
python openpyxl は自動計算ができない! (TдT)
openpyxl でセルに値を入れ、
他のセルには、openpyxl で入れるセルを参照して計算した結果が入るようにして、
さらにそのセルの計算結果を openpyxl で読み込んで処理するようにしていた (´・ω・`)
何度見ても何度試しても期待通りに動かない!!
よくよく調べてみると
エクセルの計算式は評価され、計算結果が保存されるタイミングがあるみたいで
openpyxl は保存されている計算結果を参照するから
openpyxl で入れた値を使って再計算されないことがわかった
くそぅ (´;ω;`)
何か方法はないかなと…
調べてみると xlwings, pyxlsb, win32com ではできそうな情報がありました (・・;)
まず、xlwings を試すも再計算されたり、されなかったり、
何がなんやらわからんちーな状態で1時間を浪費 (TдT)
どうしたらいいやら・・・
次に xlwings で解決できないかな、と試してみました (・∀・)ノシ
結論は 「できました!!」 ですが、小手先の対応感があります (・・;)
コードは以下、これを再計算させたいタイミングで実行しました (;´・ω・)
with xw.App(visible=False) as app:
wb = app.books.open(path)
wb.app.calculate()
ws = wb.sheets[toolname]
val = ws.range(1, 1).value
ws.range(1, 1).value = " "
ws.range(1, 1).value = val
wb.save()
wb.close()
見る人が見たらすぐわかると思いますが・・・
xlwings でエクセルをひらいて、計算をするための API をぶったたいた後、
A1 セルの値を一時退避、" " を書き込んだ後、元に戻して、保存・終了するっていう謎処理をしています (;^ω^)
ChatGPT さんも Copilot さんも上記の wb.app.calcutate() とか、なんやらほかにも紹介してくれたけど
動いたり・・・ 動かなかったり・・・ 試すたびに何か動きが違う・・・
バタついていました
結局、前述のような処理にすることで確実に再計算が行われるようになりました ('ω')v
強引だな・・・ と思いますが、Windows ってそういうところあるよね・・・ ということにして、
この件はこれで終了としようかな、と思っています ('ω')ノ
「これが本当に正しい対応の仕方だ!!」 をご存知の方、いらっしゃいましたら、ぜひご教授くださいませ m(_ _)m
python で Windows アプリを作ろう!! exe化する方法 ('ω')ノシ
python プログラムの exe化 の方法を記しておきます ![]()
実はノウハウの必要とするところなんじゃないかな、と感じたため残すこととしました
ややこしい話もあるけど、「まずは試してみたらできました!!」の体験を大事にしたいので、
ややこしい話は抜きに手順だけ示したく、以下の順で述べます
1 とにかく exe化
2 仮想環境を使って軽量化(というより重量化の抑止)
3 アイコンの封入
1 とにかく exe化
細かいことはさておき、さっさと exe化 を試したいなら以下の手順で exe ができあがります
pip install pyinstaller
pyinstaller --onefile sample.py
--noconsole はお好みで付けたらよいかな
上記の実行で、dist フォルダができて、そこに sample.exe ができあがっています
ご確認くださいませ ![]()
![]()
![]()
2 仮想環境を使って軽量化(というより重量化の抑止)
python 開発環境には 過去に pip install したライブラリもすべて入っています ('ω')
そこには exe化したいアプリで使うライブラリ以外も当然ながら存在するので、
そこで exe化 すると不要なライブラリも含まれ、とっても大きな exe ができあがっちゃいます ( ゚Д゚)ノシ
私の環境だと、100MB を超えるものが作られます!! (;^ω^)
なので、仮想環境を作って、そこで必要なライブラリを pip install して exe化します ('ω')ノ
python -m venv venv
venv\Scripts\Activate
pip install pyinstaller
pip install *** ※ *** は適宜必要なものをご指定くださいませ
python -m PyInstaller --onefile sample.py
仮想環境を終わるときは以下のコマンドをたたいておきましょう (・ω・)
うっかり忘れると、別アプリ用のライブラリをインストールするなど、悲しい事故がおきます (;^ω^)
venv\Scripts\Deactivate
3 アイコンの封入
作ったアプリには独自のアイコンを表示させたいですよね (/o\)
exe化する際のコマンド引数に --icon=icon.ico を入れるとアイコンが入るけど・・・
Window を持つアプリの場合の Window の左上のアイコンは変化しないです
調べるのに苦労しました (;^ω^)
あわせて変更する方法を記します
アイコンを指定するところを下記のように変更をして、
icon_path = get_resource_path("icon.ico")
root.iconbitmap(icon_path)
上記で呼ばれる関数(以下)を配置する
def get_resource_path(relative_path):
"""PyInstaller でパッケージ化された実行ファイルからのパスを取得"""
if getattr(sys, 'frozen', False):
# PyInstaller でビルドされた場合
base_path = sys._MEIPASS # 一時ディレクトリに展開される
else:
# 通常のスクリプト実行時
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
exe化の際のコマンドは以下のように指定する
python -m PyInstaller --onefile --icon=icon.ico --add-data "icon.ico:." sample.py
以上でいい感じにアイコンが表示されると思います ('ω')ノ
python で バルーン通知をしてみる!
2つ方法があるみたい
plyer と win10toast
それぞれ pip install plyer / win10toast をしたうえで、以下のコードで動かしてみた
・plyer
from plyer import notification
notification.notify(
title="バルーン通知したい ('ω')ノシ",
message="「激おこぷんぷん丸」 の今は?",
app_name="ii-test",
timeout=10 # 表示時間(秒)
)
・win10toast
from win10toast import ToastNotifier
toaster = ToastNotifier()
toaster.show_toast("バルーン通知したい ('ω')ノシ", "「激おこぷんぷん丸」 の今は?", duration=10)
微妙に違う結果、上が plyer 、下が win32toast ・・・
どっちがいいんだろう?
動作確認はできていませんが、軽く調べた情報を以下にまとめてみます
| 特徴 | plyer | win10toast |
| OS | マルチ(Win/Mac/Linux) | Windows10以降 |
| カスタム | アイコン、タイトル、メッセージ、表示時間 | タイトル、メッセージ、表示時間 |
| アイコン | OS による(Win は 可) | 指定不可 |
| バックグラウンド実行 | OS による(Win は 可) | 可 |
う~ん
これだけ見ると plyer 一択だな
アイコン変えられないってどういうことだろう (;^ω^)
あたしゃ、まず、変えたくなるんだけどなぁ・・・
2025-12-07
msys2 で python の開発環境を整える
AIエンジニアになれと? そういう話で python を使わなければならないことになった (;'∀') マジスカ
今まで anaconda でちょこっとお遊び程度に環境を作って動かしたことはあるんだけど、
あらためて、「本気出して頑張れ!」 ほどではないけど、環境を作って事前課題とやらをやらなければならない
数学の勉強を8時間、python の勉強を8時間せよと・・・(YouTube 動画にて・・・)
そして、そのあとに事前課題を2時間やれと・・・ (; ・`д・´)
むーーーーーーーーーーーーーーーー (・´з`・)
ひとまず、お試しで家のパソコンで試してみる
以下に、その記録をしていく ('ω')ノシ
1. msys2 をインストール
http://msys2.org
2. 連打!!
Windows キー -> msys2
# pacman -Syuu ' msys2のパッケージマネージャー? を最新状態へ
# pacman -S base-devel
# pacman -S msys2-devel
# pacman -S vim
# pacman -S git
# pacman -S openssh
# pacman -S mingw-w64-x86_64-python
3. パス設定
以下の順番になるように設定しないといけないらしい
c:\msys64\mingw64\bin
c:\Users\<UserAccountName>\AppData\Local\Microsoft\WindowsApps
※操作方法:(Win11)設定 -> システム -> バージョン情報 -> システムの詳細設定 -> 環境変数
4. 環境起動&お試し
Windows キー -> mingw or Windows キー -> msys2
# python --version
-bash: python: command not found ' (゚д゚)! 動かないんですけどっ!?
5. cmd プロンプトでは?
Windows キー -> cmd
# python --version ' 動いた
6. リトライ
Windows キー -> mingw or Windows キー -> msys2
# export PATH=$PATH:/c/msys64/mingw64/bin
# python --version ' 動いた
# vim ~/.bashrc ' 以下の記述を最後尾に追加
alias vi=vim
export PATH=$PATH:/c/msys64/mingw64/bin:/c/Users/<UserName>/AppData/Local/Programs/Python/Python312/Script/
ってことで、ひとまず、vi と python が動いたのでよかった ( *´艸`)
参考
wsl 上の ubuntu に Jenkins サーバーを設置する #001
wsl に ubuntu を動かす方法は ここ で頑張りました
Jenkins & Java11環境 をインストールは こちら を参考に、root で以下の手順で実行したが・・・
apt -y install openjdk-11-jdk
# 公開鍵の取得
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null
# Jenkins インストール時に使うもの(Jenkins のある外部リポジトリを参照するため)
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/ | tee /etc/apt/sources.list.d/jenkins.list > /dev/null
# Jenkins を使うための公開鍵を取得する
wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
# Jenkins の Debian の apt リポジトリをシステムの apt ソースリストに追加する
sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
echo deb http://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list
# apt のアプデ(Jenkins のある外部リポジトリの情報を取得)
apt update
# Jenkins のインストールapt install Jenkins
記事にあった 「E: Unable to locate package Jenkins」 エラーは改善されず、
ChatGPT にお伺いを立てて、Jenkins は apt ではなく dpkg でインストールをした (;^ω^)
wget http://pkg.jenkins.io/debian-stable/binary/jenkins_2.387.3_all.deb
dpkg -i jenkins_2.387.3_all.deb
apt-get install -f
# Jenkins の起動
systemctl start jenkins
# Jenkins の常時起動設定
systemctl enable jenkins
### ホストPC の ブラウザから http://<wsl ubuntu IPアドレス>:8080
### 初回セットアップ画面が表示され、admin パスワードを求められる
# Jenkins admin パスワードは以下で確認する
cat /var/lib/jenkins/secrets/initialAdminPassword
ここまでで、Jenkins 自体のインストールができたので、次は Jenkins の初期設定を進めていきたい
Windows(WSL) で Ubuntu を動かす
ここ で Windows 上に python 環境を作るのに msys2 を使ってみたけど、
つまり、そこで msys2 で unix 環境ができたわけだけど、
やっぱネイティブな?
純粋な unix 環境で、いろいろ試したいこともあるので、VM で unix 環境を作ることにした
やったことを記しておきます
1. WSL をインストールする
wsl --install
wsl --set-default-version 2
2. Microsoft Store から Ubuntu 24.04.1 LTS をインストールする
※ 24.04.1 LTS は 現時点(2024/11/03)最新と思われるので指定した
WSL のネットワークは 標準で NAT になっているらしい
※これだけで ubuntu が動くと思っていたけど、うごかなくて、手順3, 4, 5 をした
3. HyperV を有効にする
dism.exe /online /enable-feature /featurename:Microsoft-Hyper-V -All /norestart
4. WSL を有効化する
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /norestart
dism.exe /online /enable-feature /featurename:WindowsSubsystemForLinux /norestart ※エラーした
5. 再起動する
6. メニューから ubuntu を起動する
7. 初期設定&ssh サーバー起動する
apt update
apt upgrade
apt install -y openssh-server
# ssh サーバー起動
service ssh start
# ssh サーバーの自動起動設定
systemctl enable ssh
# ssh サーバーの起動状態の確認
service ssh status
8. root パスワードの設定&ユーザー追加(&sudo 設定)する
passwd
useradd <ユーザー名>
passwd <ユーザー名>
usermod -aG sudo <ユーザー名>
9. マシン名を変える
/etc/wsl.conf に以下の行を追加する
[network]
hostname = new-hostname
※ wsl 上の ubuntu の IP は起動するたびに変化するらしい
仮想環境であることが原因なので、固定IP運用も難しいみたい
調査していこう・・・
10. お好みで・・・
apt install net-tools
!!注意!!
・Windows の終了で、 ubuntu は自動で終了するらしい
ただし、ubuntu 上のプロセスは終了させられるので、動作保証が・・・
明確に手動で終了させる場合は PowerShell で以下のように打つようだ
wsl --shutdown
ubuntu のシェルで exit しても終わるようだ
・Windows の起動で、 ubuntu は自動起動しない
以下のようにタスクスケジューラを設定したらいいみたい(未試行なので、メモ・・・)
- 「タスクスケジューラ」を開き、「基本タスクの作成」から新しいタスクを作成します。
- 「トリガー」で「Windows にログオンしたとき」を選択。
- 「操作」で
wsl.exeを実行するよう設定します。
・Windows のファイルは /mnt/<ドライブ名> で見える♪ (・ω・)ノシ
以下、まだやっていないけど、そのうち、必要になるような気がするのでメモしておく (;^ω^)
Appendix.A ポートフォワード設定 ★まだ、うまく動かない・・・
A1. PowerShell にて以下のコマンドで設定ができる
netsh interface portproxy add v4tov4 listenport=<Windowsのポート番号> listenaddress=0.0.0.0 connectport=<WSLのポート番号> connectaddress=127.0.0.1
A2. 設定の確認
netsh interface portproxy show v4tov4
A3. 補足:設定を削除する場合
netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=<ホスト側のポート番号>
A4. ファイアーウォールの設定
New-NetFirewallRule -DisplayName "WSL Web Server Port" -Direction Inbound -Protocol TCP -LocalPort 8081 -Action Allow
openpyxl で 列幅 の設定でトラブった内容の覚書
エクセル差分抽出ツール(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)の場合に、デフォルト値を採用するようにしました
結果:オリジナルと同じ列幅で設定ができました

登録:
コメント (Atom)
ご訪問をありがとうございます ✨✨✨
八百茄子 は ソフトウェアエンジニア1名による小さな工房です 週末に スキルアップ と 八百茄子 向けのコンテンツ作成に勤しんでおります ご提供コンテンツ tools にて 八百茄子 の作成したツールをご紹介しています knowhow にて、 2x年の組込み系ソフトウェア開発...
-
ii-excel-diff エクセルを比較し、差分を抽出・可視化、結果を記した帳票を作成するツールです!! ii-excel-diff を実行いただきますと 下図のように左右に比較対象のエクセルを配置した帳票(エクセル)が出力されます 差分のあるセルをライトグリーンでハッチン...
-
ii-diff テキスト差分の可視化ツール、エクセルで2つのテキストを左右表示する WinMerge を使うことでテキストの差分は可視化されますが、WinMerge 上でしか差分を参照できません また、差分結果を記録として残すこともできなくはないですが、差分比較の操作の後に、...
-
ii-win-merge WinMerge の操作を肩代わり、結果をエクセルに出力するツール ii-win-merge を実行いただきますと WinMerge を自動実行し、結果をエビデンスとして残せる帳票を作成します!! 表紙は下図のように比較ファイルをリスト表示します ...
