1

MS Visual Studio 2012 で VB.net を使用して、Excel (2010、2007) 用のアドインを作成しています。アドインは Excel のスタイルを使用してレポートをフォーマットします。Styles コレクションを反復処理するよりも、自分のスタイルへの参照を名前で取得して、存在しない場合は例外をキャッチする方が簡単だと思いました。

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

次の詳細を含む「COMException がネイティブ/マネージド境界を超えました」という Visual Studio の例外ダイアログが引き続き表示されます。

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

この「単純な」例外をキャッチするために、考えられるすべてのことを試しました。

  1. 悪名高いキャッチオール"Catch ex As Exception"または"Catch"
  2. COMException、DISP_E_BADINDEX、workbook.styles、および「例外をキャッチできません」のいくつかの形式のさまざまな組み合わせをグーグル検索しました
  3. Common Language Runtime Exceptions -> System.Runtime.InteropServicesの下の COMException で、Thrown チェックボックスがチェックされていないことを確認しました。
  4. HandleProcessCorruptedStateExceptions属性 を追加して、破損状態例外(CSE)として処理する
  5. プロジェクトプロパティの [デバッグ] セクションで [ ネイティブ コードのデバッグを有効にする] をオンにしました。

Styles コレクション全体をループして_TitleStyleNameとの一致を探したほうがよい (場合によってはさらに高速になる) ことはわかっていますが、単純にこの Exceptionをキャッチできなかった理由を理解したいと思います。

このすべてを読むために時間を割いていただきありがとうございます。:)

4

1 に答える 1

1

私はそれが何か単純でなければならないことを知っていました!

Hans Passant が提案したように、例外設定を再確認するつもりでしたが、一見すると、[デバッグ] メニューに [例外] オプションが表示されませんでした。代わりに、下の方に [オプション] と [設定]が表示されました。これにより、[オプション] ダイアログが表示されました。Debugging -> Generalセクションで、Break when exceptions cross AppDomain or managed/native boundary を見つけまし

このボックスのチェックを外すと、try/catch ブロックが期待どおりに COMException を処理するようになりました。

概要
例外のキャッチに問題がある場合は、それが AppDomain またはマネージ/ネイティブの境界を越えているかどうかを確認してください。その場合:
1) デバッグ メニューに移動し ます 2 )
[ オプション設定] をクリックします

于 2013-03-11T02:21:50.420 に答える