私はExcelでいくつかのワークフローを自動化する必要があるプロジェクトに取り組んでおり、かなり厄介な障害にぶつかりました。このプロジェクトでは、Visual Studio ToolsForOfficeを使用してドキュメントレベルのアドインを作成しています。ユーザーは、このプロジェクトの一部であるリボンコントロールを使用して、プロジェクトの外部にあるワークブックからのワークシートのコピーを自動化します。外部ワークブックはSQLBLOBから読み込まれ、ディスクに書き込まれます。アドインコードは、各ブックを開き、ワークシートをアドインブックにコピーしてから、その外部ブックを閉じます。通常、最初のブックは問題なく機能しますが、後続のブックを開くとAccessViolationExceptionがスローされます。
public void AddSheetFromTempFile(string tempfilePath)
{
Sheets sheets = null;
Excel.Workbook workbook = null;
Excel.Workbooks books = null;
try
{
books = this.Application.Workbooks;
//Throws AccessViolationException
workbook = books.Open(tempfilePath, 0, true, 5,
String.Empty, String.Empty, true, XlPlatform.xlWindows,
String.Empty, true, false, 0, true, true, false);
sheets = workbook.Worksheets;
sheets.Copy(After: this.GetLastWorksheet());
workbook.Close(SaveChanges: false);
}
finally
{
if (sheets != null)
{
Marshal.FinalReleaseComObject(sheets);
}
if (workbook != null)
{
Marshal.FinalReleaseComObject(workbook);
}
if (books != null)
{
Marshal.FinalReleaseComObject(books);
}
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
//extension method for getting last worksheet
public static Microsoft.Office.Interop.Excel.Worksheet
GetLastWorksheet(this Microsoft.Office.Tools.Excel.WorkbookBase workbook)
{
int veryHiddenSheets = 0;
foreach(Worksheet sheet in workbook.Worksheets)
{
if(sheet.Visible == XlSheetVisibility.xlSheetVeryHidden)
{
veryHiddenSheets++;
}
}
int lastIndex = workbook.Worksheets.Count - veryHiddenSheets;
return workbook.Worksheets[lastIndex];
}
そこで、問題を繰り返し可能な一連の手順に絞り込みました。この問題は、ワークブックにN枚のシートを追加してから削除し、シートを再度追加した場合に発生しているようです。ここで提案されているネイティブデバッグを有効にしましたhttp://social.msdn.microsoft.com/forums/en-US/vsto/thread/48cd3e88-d3a6-4943-b272-6d7ea81e11e3。上記の例外の場合、次のコールスタックが表示されます。
ntdll.dll!_ZwWaitForSingleObject@12() + 0x15 bytes
ntdll.dll!_ZwWaitForSingleObject@12() + 0x15 bytes
kernel32.dll!_WaitForSingleObjectExImplementation@12() + 0x43 bytes
[External Code]
First-chance exception at 0x2ff2489e in Excel.exe: 0xC0000005: Access violation reading location 0x00000000.
A first chance exception of type 'System.AccessViolationException' occurred in PublicCompModel.DLL
An exception of type 'System.AccessViolationException' occurred in PublicCompModel.DLL but was not handled in user code
COMオブジェクトを誤用しているかどうかはわかりませんが、すべてのシートを削除してこれを複製できること、およびこれがExcelに対してローカルであることは間違いなく奇妙です。