C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.92205 の関連記事表示

<< 0 >>
■92205  エクセルファイルを作成して表示する方法について
□投稿者/ 河童 -(2019/09/01(Sun) 09:38:12)

    分類:[C#] 

    エクセルファイルを作成して表示する方法について

    フォームにあるボタンのクリック時イベントでエクセルファイルを作成して、
    それを開いて表示したいと思っています。

    エクセルファイルの作成はできたのですが、
    1.Interop.Excelで作成
    2.ClosedXMLで作成
    それぞれわからないことがあります。

    1.Interop.Excelで作成
    インストールされているエクセルのバージョンがExcel2007、2010、2019とばらばらなことと、
    プロセスが残りやすいのであまり使用しない方がいいとネット情報にありました。
    確かにタスクマネージャーのプロセスに「EXCEL」が残っていたことがありました。
    今のコード上で解放の処理はしているのですが、どこか修正すべき点はありまか?

    2.ClosedXMLで作成
    ClosedXMLでエクセルを作成して保存はできるのですが、今回は保存までは必要なく
    エクセルにデータを入力して、エクセルを開いた状態のままにしておきたいです。
    ClosedXMLで作成したエクセルを開いたままにする方法はありますか?

    using ClosedXML.Excel;
    using Excel = Microsoft.Office.Interop.Excel;
    using System.Runtime.InteropServices;

    private Microsoft.Office.Interop.Excel.Application xls = null; // Excel自体
    private Microsoft.Office.Interop.Excel.Workbook book = null; // ブック
    private Microsoft.Office.Interop.Excel.Worksheet sheet = null; // シート

    public void ExcelVisibleToggle(Microsoft.Office.Interop.Excel.Application xls, bool setting)
    {
    if (xls.Visible == !setting)
    {
    xls.Visible = setting;
    }
    }

    // エクセル使用
    private void btnExcel_Click(object sender, EventArgs e)
    {

    this.xls = new Microsoft.Office.Interop.Excel.Application();
    // Excelを非表示:レスポンス向上
    ExcelVisibleToggle(xls, false);

    this.book = xls.Workbooks.Add();

    this.sheet = (Microsoft.Office.Interop.Excel.Worksheet)this.book.Sheets["sheet1"];

    // エクセルファイルに項目名を表示
    Excel.Range w_rgn = this.sheet.Cells;
    try
    {
    w_rgn[1, 1].value = "項目名1";
    w_rgn[1, 2].value = "項目名2";
    w_rgn[1, 3].value = "項目名3";
    w_rgn[1, 4].value = "項目名4";
    w_rgn[1, 5].value = "項目名5";

    int cell_row = 2;
    // DataGridViewのソースリストをループ
    foreach (dgvKoumokuLst d in DgvKoumokuLst)
    {
    w_rgn[cell_row, 1].value = d.koumoku1;
    w_rgn[cell_row, 1].EntireColumn.AutoFit();
    w_rgn[cell_row, 2].value = d.koumoku2;
    w_rgn[cell_row, 2].EntireColumn.AutoFit();
    w_rgn[cell_row, 3].value = d.koumoku3;
    w_rgn[cell_row, 3].EntireColumn.AutoFit();
    w_rgn[cell_row, 4].value = d.koumoku4;
    w_rgn[cell_row, 4].EntireColumn.AutoFit();
    w_rgn[cell_row, 5].value = d.koumoku5;
    w_rgn[cell_row, 5].EntireColumn.AutoFit();
    cell_row++;

    }
    }
    finally
    {
    // Excelのオブジェクト開放する
    Marshal.ReleaseComObject(w_rgn);
    w_rgn = null;
    }

    // シートを選択
    ExcelVisibleToggle(xls, true); // Excel表示

    // Sheet解放
    Marshal.ReleaseComObject(sheet);
    // Book解放
    //xlBook.Close();
    Marshal.ReleaseComObject(book);

    // Excelアプリケーションを解放
    //xlApp.Quit();
    Marshal.ReleaseComObject(xls);

    }


    // ClosedXML使用
    private void btnClosedXML_Click(object sender, EventArgs e)
    {

    // エクセルオープン
    var workbook = new XLWorkbook();
    var worksheet = workbook.Worksheets.Add("CSV一覧");
    worksheet.Cell(1,1).Value = "Hello world";

    // 項目名を表示
    worksheet.Cell(1, 1).Value = "項目1";
    worksheet.Cell(1, 2).Value = "項目2";
    worksheet.Cell(1, 3).Value = "項目3";
    worksheet.Cell(1, 4).Value = "項目4";
    worksheet.Cell(1, 5).Value = "項目5";

    int cell_row = 2;
    // DataGridViewのソースリストをループ
    foreach (dgvKoumokuLst d in DgvKoumokuLst)
    {
    worksheet.Cell(cell_row, 1).Value = d.koumoku1;
    worksheet.Column("A").AdjustToContents();
    worksheet.Cell(cell_row, 2).Value = d.koumoku2;
    worksheet.Column("B").AdjustToContents();
    worksheet.Cell(cell_row, 3).Value = d.koumoku3;
    worksheet.Column("C").AdjustToContents();
    worksheet.Cell(cell_row, 4).Value = d.koumoku4;
    worksheet.Column("D").AdjustToContents();
    worksheet.Cell(cell_row, 5).Value = d.koumoku5;
    worksheet.Column("E").AdjustToContents();

    cell_row++;

    }

    // workbook.SaveAs(@"C:\Temp\test1.xlsx");

    // CmnMsgBox.Show("出力完了", 2);

    // 作成したエクセルファイルを開いて表示したい

    }
親記事 /過去ログ159より / 関連記事表示
削除チェック/

■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 するという手もありますが、それはそれで面倒かも。
記事No.92205 のレス /過去ログ159より / 関連記事表示
削除チェック/

■92207  Re[2]: エクセルファイルを作成して表示する方法について
□投稿者/ 河童 -(2019/09/01(Sun) 22:09:00)
    No92206 (魔界の仮面弁士 さん) に返信

    アドバイス、ありがとうございました。

    質問でエクセルの保存は必要ないと言いましたが、保存することにしました。
    保存するならば、ClosedXMLで処理できます。

    エクセルのバージョンがOffice 365 ProPlus に順次導入することになりました。
    xlsx形式で保存して、各自必要なときにファイルを開いてもらうようにしました。

    印刷処理をExcelから実行しようと思いましたが、
    このためだけにExcelを起動する必要もないのかなと感じだしました。
    C#で印刷処理は作成したことがないので勉強する必要があります。

    本当にいろいろ教えてくださり、ありがとうございました。
記事No.92205 のレス / END /過去ログ159より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -