質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.48%

  • C#

    9215questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Excel

    1957questions

    Excelは、マイクロソフト社が開発しているデータ集計や分析を行う表計算ソフトの一つです。文書作成や表計算、資料作成などの多彩な機能を備えており、統合パッケージであるMicrosoft Officeに含まれています。

  • Windows Forms

    178questions

    Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

  • COM

    46questions

    COM(Component Object Model)はMicrosoftによるコンポーネントテクノロジーであり、 ソフトウェアの再利用を目的とした技術を指します。

c#でExcelをOpenするとプロセスが残る(Microsoft.Office.Interop.Excel使用)

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,248

Ineda

score 21

環境

■  Windows7Pro 32bit
■ Visualstudio 2010 professional
■ Excel2016

 経緯

私は普段.net環境からExcelを呼び出す場合にはClosedXMLを使用しています。
実務でCOMを使用したエクセルプロセス解放に悩まされたため、ライブラリを使用することに決めていました。

ただ、「突き詰めよう」との気持ちが突然芽生え、こちらのサイトにある方法を試してみる事にしました。

以下のサイトにCOMの正しい解放の仕方がアップされていました。
Excelファイルを C# と VB.NET で読み込む "正しい" 方法

リンク先のソースを参考に以下のソースを作成しました。
プロセスの確認はタスクマネージャーから行います。

■非define時

  1. 100回ブックをオープンする
  2. ブックを保存する

■define時

  1. 100回ブックをオープンする。
  2. 一番左端のセルにABCDEFを入力する
  3. ブックを保存する
//#define __VALUE_SET__

using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Excel;

namespace ConsoleApplication1
{
    class Program
    {



        static void Main(string[] args)
        {

            for (int i = 1; i<=100; i++)
            {
                int no = i % 6 + 1;

                string fileName = Path.Combine(@"c:\sample", no.ToString() + ".xlsx");
                Console.WriteLine(fileName);

                // エクセルオープン
                OpenExcel(fileName);
            }
        }




        private static void OpenExcel(string fileName)
        {
            var excelApplication = new Microsoft.Office.Interop.Excel.Application();

            try
            {
                Workbooks workbooks = excelApplication.Workbooks;

                try
                {
                    Workbook workbook = workbooks.Open(fileName);

                    try
                    {
                        Sheets worksheets = workbook.Sheets;

                        try
                        {
                            Worksheet worksheet = worksheets[1];

                            try
                            {
#if __VALUE_SET__
// Rangeを使用して値をセットするとプロセスが解放されない

                                Range range1 = worksheet.Cells[1, 1];

                                try 
                                { 
                                    range1.Value = "ABCDEFG";
                                }
                                finally { Marshal.ReleaseComObject(range1); }
#endif

                                workbook.Save();

                            }
                            finally { Marshal.ReleaseComObject(worksheet); }

                        }
                        finally { Marshal.ReleaseComObject(worksheets); }

                    }
                    finally
                    {
                        if (workbook != null)
                        {
                            workbook.Close(false);
                        }
                        Marshal.ReleaseComObject(workbook);
                    }
                }
                finally { Marshal.ReleaseComObject(workbooks); }
            }
            finally
            {
                if (excelApplication != null)
                {
                    excelApplication.Quit();
                }

                Marshal.ReleaseComObject(excelApplication);
            }
        }
    }
}

 問題 Rangeを使用して値をセットするとプロセスが解放されない

defineしている「__VALUE_SET__」の部分ですが、この部分を通るとプロセスが解放されずに残り続けます。
単純に開いて保存するだけであれば、プロセスは全て解放されています。

値設定時、何か私の方法が間違っているでしょうか?

詳しい方がいれば、ご教示お願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+5

worksheet.Cells[1, 1]ですが

  1. worksheet.Cells→シートの全てのセルを示すRange
  2. シートの全てのセルの中の[1, 1]Range

worksheet.Cells[1, 1]の二つのRangeが隠れています。

このうち「シートの全てのセルを示すRange」の解放が漏れているのだと思われます。

Officeの解放周りについては以下の記事も参考になると思います。

Office オートメーションで割り当てたオブジェクトを解放する – Part1 – Japan Office Developer Support Blog

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/26 19:56

    指摘された点修正したら、100回やってもプロセス漏れはありませんでした!
    あんたスゴイヨッ!!

    キャンセル

同じタグがついた質問を見る

  • C#

    9215questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Excel

    1957questions

    Excelは、マイクロソフト社が開発しているデータ集計や分析を行う表計算ソフトの一つです。文書作成や表計算、資料作成などの多彩な機能を備えており、統合パッケージであるMicrosoft Officeに含まれています。

  • Windows Forms

    178questions

    Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

  • COM

    46questions

    COM(Component Object Model)はMicrosoftによるコンポーネントテクノロジーであり、 ソフトウェアの再利用を目的とした技術を指します。