2017-07-11 7 views
-1

アクティブシートを処理し、別のExcelアプリケーションを開き、別のシートに書き込むExcelアドインを作成しました。私はこのプログラムが終了したときにユーザーに任せられるのでExcelを閉じたくはありません。私のプログラムが実行されるとき、私はタスクマネージャでEXCEL.exeを見ることができます。それが終わると、私はまだそれを見ています。それは私が期待しているものです.Excelを閉じると消えてしまいます。 ReleaseComObjectを呼び出す必要があります。別のExcelファイルを作成するExcelアドインでCOMオブジェクトをクリーンアップする方法はありますか?

public class ProcessExcel { 
Worksheet activeSheet; 

ProcessExcel_Click(object sender, EventArgs e) 
{ 
    //Do I need to break these into variables and/or do I need to dispose of them? 
    var addIn = Globals.ThisAddIn; 
    var application = addIn.Application; 
    var workbook = application.ActiveWorkbook; 

activeSheet = workbook.ActiveSheet; 

    var processor= new Processor(activeSheet, _bank); 

      var processedCells = processor.Process(); 

      CreateExcelFile(); 

      GenerateOutput(processor, processedCells); 
} 

    private void CreateExcelFile() 
     { 

      var xlApp = new Microsoft.Office.Interop.Excel.Application(); 


      if (xlApp == null) 
      { 
       MessageBox.Show("EXCEL could not be started"); 
       return; 
      } 

      xlApp.Visible = true; 

      var workbooks = xlApp.Workbooks; 

      var wb = workbooks.Add(); 
      xlApp.DefaultSaveFormat = xlFileFormat; 

      var worksheets = wb.Worksheets; 

      activeSheet = worksheets.Add(); 
      activeSheet.Name = "Output"; 


      if (activeSheet == null) 
      { 
       MessageBox.Show("Worksheet could not be created"); 
       return; 
      } 

      var outputSheetColumns = activeSheet.Columns; 

      foreach (var item in data.Columns) 
      { 
       if (item.TargetDataType != null) 
       { 
        if (item.TargetDataType.ToLower() == DataType.Text.ToLower()) 
        { 
         outputSheetColumns[item.TargetColumnNumber].Numberformat = NumberFormat.Text; 
        } 
       } 

      } 


     } 

    private void GenerateOutput(Processor processor, ProcessedCells processedCells) 
    { 
     var cells = activeSheet.Cells; 

     if (data.IncludeHeader) 
     { 
      processor.SetHeaders(activeSheet); 
     } 

     foreach (var cell in processedCells.ValidCells) 
     { 
      var currentCell = cells[cell.RowNumber, cell.ColumnNumber]; 
      currentCell.Value2 = cell.Value; 
     } 
    } 
} 

あなたは私がすべてのCOMオブジェクトの変数を使用し、2個のドットを避ける(と思う)午前しようとしています、上から見ることができるように:ここに私の現在のコードです。私は、クリーンアップのために、以下の方法を持っていますが、確かではない、それを使用するオブジェクトを上とする場合:

private void releaseObject(object obj) 
    { 
     try 
     { 
      System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); 
      obj = null; 
     } 
     catch (Exception ex) 
     { 
      obj = null; 
      MessageBox.Show("Unable to release the Object " + ex.ToString()); 
     } 
     finally 
     { 
      GC.Collect(); 
     } 
    } 

私はReleaseComObjectが必要ではないかもしれないし、私が呼び出すことができることを見た:

 GC.Collect(); 
     GC.WaitForPendingFinalizers(); 
     GC.Collect(); 
     GC.WaitForPendingFinalizers(); 

場合ユーザーはExcelアプリケーションを閉じることに責任があり、上記は必要ですか?

答えて

0

残念ながら働く悪いソリューションは、Workbookオブジェクトを終了するには、相互運用機能に組み込まれた機能を使用してプロセス

System.Diagnostics.Process pro = ExcelProcess.GetExcelProcess(ExcelApp); 
pro.Kill(); 

[DllImport("user32.dll")] 
static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId); 

public static System.Diagnostics.Process GetExcelProcess(oExcel.Application excelApp) 
{ 
    int id; 
    GetWindowThreadProcessId(excelApp.Hwnd, out id); 
    return System.Diagnostics.Process.GetProcessById(id); 
} 
+0

を開くことによって、あなたが作成したプロセスを終了しますWorkbook.Close()メソッドを呼び出した後、それを閉じる。 – xaisoft

+0

このコードは、C#コードが処理で使用するプロセスIDをキャッチします。それはそのプロセスを殺す。あなたは何かをするために多くのプロセスを呼び出すことができます。これにより、ExcelAppオブジェクトに関連付けられているプロセスのみが強制終了されます。 –

+0

しかし、私はC#コードが開いたままにするために使用するExcelアプリケーションを必要としています。 – xaisoft

0

を殺すことです。

using Excel = Microsoft.Office.Interop.Excel; // skip a lot of redundant typing 

// declare application/workbook/worksheet objects 
Excel.Application applicationObject = new Excel.Application(); 
Excel.Workbook workbookObject; 
Excel.Worksheet worksheetObject; 


workbookObject = applicationObject.Open(/* lot of parameters go here */); 
worksheetObject = workbookObject.Sheets["SheetName"]; 
DoThings(worksheetObject); 

// finished working with sheet, time to close it 
workbookObject.SaveAs(/* necessary parameters */); 
workbookObject.Close(/* necessary parameters */); 

あなたは、私は、ユーザーが欲しいので、実行していることを得意と私が欲しい、私のアプリケーションが終了したとき、それは、私の場合は

関連する問題