前提・実現したいこと
開発環境:C# VS2017 Excel2013(32bit) windows10
テンプレートのExcelファイルを用意し、テンプレートファイルにはtempシートとstampシートがあります。
stampシートには、印影を用意しており、オートシェイプで作成しています。
実行時に、オートシェイプのテキストに姓と日付を設定し、オートシェイプのあるセルごとtempシートにコピーしています。
その後、stampシートを削除します。
SaveAsにて別名に保存します。
上記手順にて処理を行うとまれに、Book.Close時にエラーが発生するため困っています。
Book.Close時にエラーが発生するときは、Excelのプロセスが解放されず残っています。
どこかに開放漏れがあるのではと思っています。
お力を貸して頂けないでしょうか。
発生している問題・エラーメッセージ
System.Runtime.InteropServices.COMException (0x80010105): サーバーによって例外が返されました。 (HRESULT からの例外:0x80010105 (RPC_E_SERVERFAULT))
場所 Microsoft.Office.Interop.Excel._Workbook.Close(Object SaveChanges, Object Filename, Object RouteWorkbook)
該当のソースコード
C#(VS2017) ■■■■■メイン処理■■■■■ ---------------------------------------------------------------------- Application xlsApp = null; Workbook xlsWorkBook = null; Workbooks xlsWorkBooks = null; Sheets xlsWorkSheets = null; Worksheet xlsTempSheet = null; Worksheet xlsStampSheet = null; try { xlsApp = new Application(); xlsApp.Visible = false; xlsApp.DisplayAlerts = false; xlsApp.ScreenUpdating = false; xlsWorkBooks = xlsApp.Workbooks; xlsWorkBook = xlsWorkBooks.Open(System.IO.Path.Combine(System.Windows.Forms.Application.StartupPath, TEMPLATE_FILE)); xlsWorkSheets = xlsWorkBook.Worksheets; xlsTempSheet = xlsWorkSheets["temp"]; //--------------------------------------------------- //検印欄の処理 xlsStampSheet = xlsWorkSheets["stamp"]; int data_index = 7; //7行目から開始 foreach (var row in query) { //印1 string name = "test"; string date = "date"; SetShapeItemText(ref xlsStampSheet, "name1", name); SetShapeItemText(ref xlsStampSheet, "date1", date); StampCellCopy(ref xlsStampSheet, "J1", ref xlsTempSheet, string.Format("J{0}", data_index)); //印2 string name2 = row["name2"].ToString(); string date2 = "date"; if (!string.IsNullOrEmpty(name2)) { SetShapeItemText(ref xlsStampSheet, "name2", name2); SetShapeItemText(ref xlsStampSheet, "date2", date2); StampCellCopy(ref xlsStampSheet, "B1", ref xlsTempSheet, string.Format("B{0}", data_index)); } data_index++; } System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlsStampSheet); xlsStampSheet = null; ここ ----------------------------------------------------- //stampシートの削除 Worksheet xlsDelWorkSheet = xlsWorkSheets["stamp"]; xlsDelWorkSheet.Delete(); System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlsDelWorkSheet); xlsDelWorkSheet = null; ----------------------------------------------------- //--------------------------------------------------- //保存 string outPath = System.IO.Path.Combine(_outputPath, "test.xlsx"); System.IO.File.Delete(outPath); xlsWorkBook.SaveAs(outPath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); xlsWorkBook.Close(Type.Missing, Type.Missing, Type.Missing); return true; } catch (Exception ex) { return false; } finally { if (xlsStampSheet != null && System.Runtime.InteropServices.Marshal.IsComObject(xlsStampSheet)) { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlsStampSheet); xlsStampSheet = null; } if (xlsTempSheet != null && System.Runtime.InteropServices.Marshal.IsComObject(xlsTempSheet)) { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlsTempSheet); xlsTempSheet = null; } if (xlsWorkSheets != null && System.Runtime.InteropServices.Marshal.IsComObject(xlsWorkSheets)) { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlsWorkSheets); xlsWorkSheets = null; } if (xlsWorkBook != null && System.Runtime.InteropServices.Marshal.IsComObject(xlsWorkBook)) { try { //xlsWorkBook.Saved = true; //xlsWorkBook.Close(false, Type.Missing, Type.Missing); } catch (Exception) { } finally { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlsWorkBook); xlsWorkBook = null; } } if (xlsWorkBooks != null && System.Runtime.InteropServices.Marshal.IsComObject(xlsWorkBooks)) { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlsWorkBooks); xlsWorkBooks = null; } GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); if (xlsApp != null && System.Runtime.InteropServices.Marshal.IsComObject(xlsApp)) { xlsApp.ScreenUpdating = true; xlsApp.DisplayAlerts = true; xlsApp.Quit(); System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlsApp); xlsApp = null; } GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); } ---------------------------------------------------------------------- メイン処理ここまで ここからメソッド /// <summary> /// 印影に値を設定する /// </summary> /// <param name="xlsStampSheet"></param> /// <param name="stamp_Item_name"></param> /// <param name="value"></param> protected void SetShapeItemText(ref Worksheet xlsStampSheet, string stamp_Item_name, string value) { Shapes xlsShapes = null; Shape xlsShape = null; TextFrame xlsTextFrame = null; Characters xlsCharacters = null; try { xlsShapes = xlsStampSheet.Shapes; xlsShape = xlsShapes.Item(stamp_Item_name); xlsTextFrame = xlsShape.TextFrame; xlsCharacters = xlsTextFrame.Characters(); xlsCharacters.Text = value; } finally { if (xlsCharacters != null && System.Runtime.InteropServices.Marshal.IsComObject(xlsCharacters)) { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlsCharacters); xlsCharacters = null; } if (xlsTextFrame != null && System.Runtime.InteropServices.Marshal.IsComObject(xlsTextFrame)) { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlsTextFrame); xlsTextFrame = null; } if (xlsShape != null && System.Runtime.InteropServices.Marshal.IsComObject(xlsShape)) { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlsShape); xlsShape = null; } if (xlsShapes != null && System.Runtime.InteropServices.Marshal.IsComObject(xlsShapes)) { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlsShapes); xlsShapes = null; } } } protected void StampCellCopy(ref Worksheet xlsStampSheet, string stamp_cell, ref Worksheet xlsDestinationSheet, string destination_cell) { Range xlsStampRange = null; Range xlsDestinatioRange = null; try { xlsStampRange = xlsStampSheet.Range[stamp_cell]; xlsDestinatioRange = xlsDestinationSheet.Range[destination_cell]; xlsStampRange.Copy(xlsDestinatioRange); } finally { if (xlsDestinatioRange != null && System.Runtime.InteropServices.Marshal.IsComObject(xlsDestinatioRange)) { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlsDestinatioRange); xlsDestinatioRange = null; } if (xlsStampRange != null && System.Runtime.InteropServices.Marshal.IsComObject(xlsStampRange)) { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlsStampRange); xlsStampRange = null; } } }
試したこと
stampシートの削除の部分をコメントにすると、エラーにはなりませんでした。
Close処理の位置を変えてみたりもしましたが、結果は変わらずエラーが発生します。
検印欄の処理を行わないと、stampシートを削除してもエラーは発生しませんでした。
おそらく、stampシートの操作で、解放漏れがあるからだとは思いますが。。。
回答2件
あなたの回答
tips
プレビュー