■92206 |
Re[1]: エクセルファイルを作成して表示する方法について |
□投稿者/ 魔界の仮面弁士 -(2019/09/01(Sun) 17:44:36)
| ■No92205 (河童 さん) に返信 > 2.ClosedXMLで作成 > ClosedXMLでエクセルを作成して保存はできるのですが、今回は保存までは必要なく > エクセルにデータを入力して、エクセルを開いた状態のままにしておきたいです。 > ClosedXMLで作成したエクセルを開いたままにする方法はありますか?
ClosedXML の場合、SaveAs メソッドが Stream への保存をサポートしているので、この辺と組み合わせてみるとか。 http://atata.sakura.ne.jp/net/chap29.html
あるいは、シート内容を表示することだけが目的なら、ReoGrid を使うという手もあります。 オンメモリでのワークブック生成が可能ですし、それを表示するためのコントロールも用意されています。 https://reogrid.net/jp/document/
> 1.Interop.Excelで作成 個人的には積極的にお奨めはしていませんが、Excel の機能を十分に呼び出せる 強力な方法ではありますので、用途に応じて使い分けるものかなと思います。
> インストールされているエクセルのバージョンがExcel2007、2010、2019とばらばらなことと、 バージョンによって、void 戻り値なメソッドが object 戻り値なメソッドに変化したり、 省略可能な引数が追加されたりといった拡張が行われることがあります。
新しく追加した機能を使わないようにすれば、VBA においては大きな差にはなりませんし、 COM レベルにおいても、ディスパッチ ID と不可視属性の組み合わせが使われることで ある程度の互換性が保たれてはいるのですが、それでも、上位バージョンのライブラリを使って 開発したアプリケーションを下位バージョン環境で動作させようとした場合には、 問題が生じる可能性があります。
また、ストアアプリ版と Windows Installer 版とでの動作の違いや、Office 365 での 更新サイクルの短期化などがあるため、バージョン違いを正確に考慮して コーディングするのは、ますます難しくなってきています。
> プロセスが残りやすいのであまり使用しない方がいいとネット情報にありました。 解放手続きの話という事で、このあたりも。 https://social.msdn.microsoft.com/Forums/ja-JP/0d9c6273-bade-4f6a-a0de-5adb748d15eb/office?forum=officesupportteamja
たとえば、COM オブジェクトを引数に渡すタイプのメソッドを呼び出す場合、 参照設定なしで dynamic や object を渡した場合と、 PIA を経由で明示的な Excel の型として渡した場合と、 動的生成された IA の型を通じて渡した場合とで、参照カウントの増数が異なるらしく、 ReleaseComObject 時の戻り値の値が変化したこともあります。
> // Excelを非表示:レスポンス向上 アプリケーションを非表示にすることがレスポンス向上に繋がるかは、実はケースバイケースです。 シートを非表示にしたり、描画抑制するなどして操作する方法であれば、レスポンス向上になることが多いのですが、 Application.Visible = false; については、向上する場合もあれば、むしろ低下することもあるのでご注意ください。
本体が非表示となった場合、Excel.exe がバックグラウンド処理に回されることから、実行環境によっては、 処理速度が半分未満に低速化することがあります。OS 設定や プロセッサ構成などの要因によって、 謙虚に反映されてしまう場合もあれば、問題無い場合もありますので、実際の環境で試した上で判断が必要です。
> this.book = xls.Workbooks.Add(); books = xls.Workbooks; book = books.Add(); とします。Marshal.IsComObject(books) が true である場合、 book のみならず books も解放対象となります。
> this.sheet = (Microsoft.Office.Interop.Excel.Worksheet)this.book.Sheets["sheet1"]; こちらも同様で、 // sheets = book.Worksheets; sheets = book.Sheets; sheet = (Microsoft.Office.Interop.Excel.Worksheet)sheets["sheet1"]; としたうえで、Marshal.IsComObject(sheets) が true なら、sheets も解放対象です。
> w_rgn[1, 1].value = "項目名1"; Excel.Range w_rgn11 = w_rgn[1, 1]; w_rgn11.Value = "項目名1"; if (Marshal.IsComObject(w_rgn11)) { Marshal.ReleaseComObject(w_rgn11); }
なお、C# のバージョンが古い場合には、 w_rgn11.set_Value(Type.Missing, "項目名1"); の形式が求められることがあります。今回は当てはまりませんけれども。
> w_rgn[cell_row, 1].EntireColumn.AutoFit(); これも、EntireColumn が返すオブジェクトを変数に受けておくべきです。
rngEntireColumn.AutoFit(); if (Marshal.IsComObject(rngEntireColumn)) { Marshal.ReleaseComObject(rngEntireColumn); }
個別の解放手続き面倒であれば、アプケーションドメインを別途立てて実行し、 作業した AppDomain ごと Unload するという手もありますが、それはそれで面倒かも。 |
|