Я работаю над проектом, где мне нужно автоматизировать некоторые рабочие процессы в Excel, и я ударил довольно неприятный блокпост. В проекте я использую Visual Studio Tools для Office для создания надстройки уровня документа. Пользователь использует ленточный элемент управления, который является частью этого проекта, для автоматизации копирования рабочих листов из книг, внешних по отношению к проекту. Внешние книги загружаются из SQL-блоков и записываются на диск. Код надстройки открывает каждую рабочую книгу, копирует рабочий лист в книгу надстроек и закрывает эту внешнюю книгу. Как правило, первая книга работает очень хорошо, но открытие следующей книги вызовет исключение AccessViolationException.AccessViolationException в ThisWorkbook.Application.Workbooks.Open
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. Когда вышеописанное исключение, я вижу следующий стек вызовов.
[email protected]() + 0x15 bytes
[email protected]() + 0x15 bytes
[email protected]() + 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.
Пожалуйста, отметьте свой ответ в качестве ответа. – Artemix