16

ここ数日間、Excel 2007 の問題と戦っています。以下は、関連する可能性があると私が考えることができるすべての事実のリストです。

  1. IDetailSheetは、いくつかのメソッドを持つ VBA プロジェクトで宣言されたクラスであり、インスタンス化 (抽象化) できないようにクラス初期化子でエラーをスローします。

  2. Option Explicitはすべてのモジュールで設定されます。

  3. VBA プロジェクトの 10 個のワークシートがIDetailSheetを実装 し、クリーンにコンパイルします (プロジェクト全体と同様)。

  4. CDetailSheetsは、Collection オブジェクトをラップし、Collection オブジェクトをIDetailSheetの Collection として公開する、VBA プロジェクトで宣言されたクラスです。また、すべてのコレクション メンバーに対してIDetailSheetの特定のメソッドを実行するための追加メソッドもいくつか公開しています。

  5. クラス初期化子 ( Workbook _ Openイベント ハンドラーから呼び出され、グローバル変数に割り当てられる) で、CDetailSheetは次のコードを実行して、プライベート コレクションDetailSheetsを設定します。

    Dim sht as EXCEL.WorkSheet
    For Each sht in ActiveWorkbook.Worksheets
      If TypeOf sht is IDetailSheet Then
        Dim DetailSheet as IDetailSheet
        Set DetailSheet = sht
        DetailSheets.Add DetailSheet, DetailSheet.Name
      End If
    Next sht
    
  6. 特定のリボン コールバックでは、次のコードが実行されます。

       If TypeOf ActiveWorkbook.ActiveSheet is IDetailSheet Then
          Dim DetailSheet as IDetailSheet
          Set DetailSheet = ActiveWorkbook.ActiveSheet
          DetailSheet.Refresh  *[correction]*
       End If
    
  7. 他の安定性の問題が確認された後、すべての ActiveX コントロールが Workbook から削除されました (最初は数十個ありました)。Fluent Interface リボンは、もともと ActiveX コントロールに関連付けられていた機能を置き換えるために作成されました。

  8. 企業テンプレートからの Hyperion アドインがありますが、このワークブックでは使用されていません。

結局のところ、ワークブックを実行すると、次のような症状が発生します。

  • CDetailSheets Initializer では、1 (最も一般的) から、場合によっては 2 または 3 まで、IDetailSheet の任意の数のインスタンスが認識されます。(常に同じとは限りませんが、セットの前にいると認識される可能性が高くなるようです。)
  • IDetailSheet 実装のインスタンスが CDetailSheets 初期化子で検出された場合 (および、私が判断できる限りそのようなインスタンスのみ) は、TypeOfによっても認識されます。リボン コールバックにあります。

ほとんどのTypeOf ... Is操作が失敗する理由を誰でも説明できますか? または、問題を解決する方法は?

機能を動作させるために、手動で v テーブル (つまり、大きな醜いSelect Case ... End Selectステートメント) を作成することに頼りましたが、実際には、そのようなコードの横に自分の名前があるのはかなり恥ずかしいと思います。それに加えて、それは将来のメンテナンスの悪夢であることがわかります.

古い p コードの問題ではないかと考えて、展開された XLSM zip から Project.Bin ファイルを削除し、すべての VBA コードを手動でインポートし直しました。変更はありません。また、プロジェクト名を IDetailSheet のすべての使用箇所に追加してmiFab.IDetailSheetにしようとしましたが、やはり役に立ちませんでした。( miFabはプロジェクト名です。)

4

3 に答える 3

8

CallByName を使用してごまかす方法がいくつかあります。何らかの方法でこのバグを回避する必要があります。

簡単な汚い例

実装行で始まるすべてのシートには、パブリック GetType 関数が必要です。「TestSheet」サブをリボンのボタンに付けました。関数を示すために、返された型名をセル A1 に入力します。

モジュール1

'--- Start Module1 ---
Option Explicit

Public Sub TestSheet()
  Dim obj As Object
  Set obj = ActiveSheet
  ActiveSheet.[A1] = GetType(obj)
End Sub

Public Function GetType(obj As Object) As String
  Dim returnValue As String
  returnValue = TypeName(obj)
  On Error Resume Next
  returnValue = CallByName(obj, "GetType", VbMethod)
  Err.Clear
  On Error GoTo 0
  GetType = returnValue
End Function
'--- End Module1 ---

シート1

'--- Start Sheet1 ---
Implements Class1
Option Explicit

Public Function Class1_TestFunction()
End Function

Public Function GetType() As String
    GetType = "Class1"
End Function
'--- End Sheet1 ---
于 2013-09-03T22:34:35.663 に答える