Я использую VB.net в MS Visual Studio 2012 для создания надстройки для Excel (2010, 2007). Надстройка использует стили Excel для форматирования отчетов. Вместо того, чтобы перебирать коллекцию стилей, я подумал, что будет проще попытаться получить ссылку на мой стиль по имени и перехватить исключение, если оно не существует.
Imports xi = Microsoft.Office.Interop.Excel
<ComVisible(True)> _
<ClassInterface(ClassInterfaceType.None)> _
Public Class ReportOptions
Implements IReportOptions
Private Const _TitleStyleName As String = "TitleStyle"
Private Const _SubtitleStyleName As String = "SubtitleStyle"
Public Sub SetDefaults() Implements IReportOptions.SetDefaults
Dim MyApp As xi.Application
Dim wb As xi.Workbook
Dim styles As xi.Styles
Dim SubtitleStyle As xi.Style
Dim TitleStyle As xi.Style
MyApp = GetObject(, "Excel.Application")
wb = MyApp.ActiveWorkbook
styles = wb.Styles
Try
SubtitleStyle = styles.Item(_SubtitleStyleName) 'Exception here
Catch ex As COMException
SubtitleStyle = styles.Add(_SubtitleStyleName)
End Try
TitleStyle.Font.Name = "Calibri"
'More code setting style values
'Code to clean up the COM Objects...
End Sub
End Class
Я продолжаю получать диалоговое окно исключения Visual Studio для «COMException пересекло собственную/управляемую границу» со следующими подробностями:
Invalid index. (Exception from HRESULT: 0x8002000B (DISP_E_BADINDEX))
at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
at Microsoft.Office.Interop.Excel.Styles.get_Item(Object Index)
at ReportClassLibrary.ReportClassLibrary.ReportOptions.SetDefaults() in <Path>\ReportClassLibrary.vb:line 68
Я пробовал все, что мог придумать, чтобы поймать это «простое» исключение:
- печально известное универсальное "Catch ex As Exception" или "Catch".
- Погуглил различные комбинации COMException, DISP_E_BADINDEX, workbook.styles и несколько форм «не удается поймать исключение».
- проверил, что флажок Thrown НЕ установлен для COMException в разделе Common Language Runtime Exceptions -> System.Runtime.InteropServices
- обработка его как исключения поврежденного состояния (CSE) добавив атрибут HandleProcessCorruptedStateExceptions
- Флажок Включить отладку собственного кода в разделе "Отладка" свойств проекта.
Я понимаю, что может быть лучше (и, возможно, даже быстрее) просмотреть всю коллекцию стилей в поисках соответствия _TitleStyleName, но я бы предпочел понять, почему я не смог просто Перехватите это исключение.
Спасибо, что нашли время, чтобы прочитать все это. :)