[C#] ClosedXMLが使えそうで使えなくて泣いた話

  • 投稿日:
  • by
  • Category:

先に結論

ClosedXMLは図形(Shape)に対応しておらず保存時に全部消えるから気をつけな!(コメントも消えるっぽい)

EEPlusは図形に対応してるみたいだけど商用ライセンスだから気をつけな!

 

話せば長くなるのだが...

IT土方あるあるネタの一つに「エクセル勤務表」というものがある。

その名の通り「Excelで勤怠管理をすること」を指すのだが、

単純に勤怠管理システムが存在せず(IT企業なのに!)Excelを使っているだけだったり、いわゆるSESで入っている他社メンバーの勤務実績を受け渡しするのにExcelファイルが便利だったり、理由は色々あるが、未だに根強く残っているのである。

 

 

実際の話

エクセル勤務表自体はそれほど悪いものでもない。

大抵の場合、出退勤時刻を入力すればあとはマクロや数式によって自動計算される仕組みになっている。流石にIT企業なのでそれぐらいは実装されている。

Excelを起動して時刻を入力するだけなら毎日1分で済むので、これだけであれば大した負担にもならない。

 

問題なのは企業体質

そう、Excelに罪は全くないのだ。問題はシステムにコストをかけようとしない企業にある。こういう企業は何かと「人の手」で解決させようとしてくる。IT企業なのに

愚痴は程々にして、具体的に何があったのかというと「管理強化のため今後は週報を送ってください」とExcelシートが送られてきたのだ。

まぁ週報はよくある話なのだが、大仰なExcelを作ってあれもこれも事細かに報告をさせようとするのには辟易としてしまう。何かしてくれるならいいんだけど、結局は「上に報告するための資料」でしかないわけで。

それだけでは飽き足らず、更には「月次の勤務実績に加え、週次での勤務実績も週報と一緒に送ってください」という指示も来た。

つまり週次でも勤務表を送ってこいという話なのだが、たたでさえ週報を書くのに手間がかかっている上、既に月次で送っている勤務実績を週次でも送付するとなると時間がかかって仕方がない。

(その後、更に週次で電話での状況確認も加わったことは割愛する。何なんだ一体)

 

手間がかかるならシステム化しちゃえばいいじゃない

毎日の出退勤時刻を入力すれば月次の勤務表、週報(週次の勤務表)Excelがアウトプットされるプログラムを作ればいい。

ということでC#.NETで入力画面を作り、データをSQL Serverに保存する仕組みをサクッと作った。

これでボタンポチで勤務表と週報Excelファイルに勤務実績が転記される。完璧だ。

Excel出力にはClosedXML(V0.97)を使った。.NET FrameworkのBindingSourceを使ってDBテーブルとDataGridViewの連携をやってみたかったので良い教材にもなった。

 

と思ったら落とし穴が

気分上々で出来上がった勤務表を送信したが、後日「送ってもらった勤務表が一部欠けている」と連絡があった。

出力したExcelファイルをよく見てみるとテキストボックスやレクタングル等の図形が消えてしまっている。

誤操作で消してしまったのかな?と思い復活させたが、またポチると消えてしまう。なんてこった。

調べてみたところ、ここに書いてある通りClosedXMLは図形(Shape)には対応していないらしい。

GithubのIssueには「保存時に図形が消える」問題が報告されており、これがまだ解決していないのかもしれない。

 

ClosedXMLは諦めてEPPlusを試してみる

図形がないExcelシートならよかったのだが、ふんだんに使われているご立派な勤務表なので困ってしまった。

そこで先ほどの記事で紹介されていたEPPlusを試してみた。

Nugetからパッケージ(最新版6.1.1)をインストールすれば使用できるが、Ver.5以降は商用ライセンス(非商用/無料版もあり)なので注意。

記法はClosedXMLとそう大きく変わらないので移植は簡単だったが、保存(WorkBook.Save())時にInvalidOperationExceptionとぬるりで落ちる謎の問題が発生してしまい、結局使えなかった。

おそらく勤務表Excelファイルにシートパスワードなり特殊な設定がしてあるのにEPPlusが対応していないのが原因だと思われるが、ClosedXMLでは起きていなかったのでEPPlusも完璧ではないようだ。

 

外部からのExcelファイル更新を諦める

大変残念だが外部プログラムからExcelファイルを更新するのは諦めた。

最後の手段「COM参照」が残ってはいるが、あれだけは避けたい。

結局はExcelのPower QueryでSQL Serverのデータをシートに取り込み、VLOOKUPで当該日時のデータがあればセルに表示するようにした。

Excelファイルを起動する度にSQL Serverからのデータ読み込みを待たないといけないのは手間だが、変にExcelファイルが壊れるよりはいいだろう。

 

結局、

OSSでExcelの仕様を完全に再現するのは難しいようだ。商用ライセンスのあるEPPlusでも思い通りのことはできなかったのは想定外だが。

「何で使い勝手の悪いCOM参照を使うんだろう」と思っていたが、色々やろうとすると何だかんだCOM参照に頼らざるを得ないんだなぁと思うなど。

結局Excelのことは(直接か間接かはあるが)Excelにやってもらうのがいいということなんだろう。

コメントする