この問題を数日間追跡してきたので、ここに投稿して、同じ問題を抱えている他の人を助け、原因について詳しく知ることができると思いました. この投稿の最後に、問題のコードを 2 つのクラス モジュールに単純化しました。
基本的に、簡略化されたシナリオは次のとおりです。Child が Parent を実装する、Parent と Child の 2 つのクラス モジュール。親のどこかに行がTypeOf Me Is Child
あり、そこにMe
は任意のオブジェクトが含まれる可能性があります。
私の理解では、TypeOf...Is
行が P コード (デバッグ > コンパイル、またはメソッドの呼び出し) にコンパイルされ、ファイル (.xlsm または .xlsb) に保存されると、ファイルが正しく開かれません。コードは正常に実行されますが、ファイルを保存して閉じ、再度開くと、開く (または VBE を開く) ときにエラーが発生し、またはのいずれInvalid data format
かが表示さError accessing file. Network connection may have been lost
れ、親モジュールを開くことができなくなり、VBA を実行することもできなくなります。 (?1=1
イミディエイト ウィンドウで試してみると、同じエラーが発生します)。
TypeName()
の代わりに を使用して型がチェックされている場合TypeOf...Is
、この問題は発生しません (これは私のプロジェクトで使用した解決策です)。
ここで何がうまくいかないのか、または少なくとも問題の原因(Pコード)に関して私が正しい軌道に乗っていることを確認することはできますか?
PSはい、親が子供の知識を持っているのはデザインが悪いことは承知していますが、再設計に時間をかける価値のない1回限りのプロジェクトの終わりに近づいていました。
便利なリンク:
- VBA のコードの状態と、ファイルに保存される内容について説明します。 http://orlando.mvps.org/VBADecompilerMore.asp?IdC=OrlMoreWin#WhatItIs
クラス モジュール:
親:
Option Explicit
' Class: Parent
' The problem (so far as I can tell):
' When the compiled version of the method below is saved to the file, the file
' will no longer load properly. Upon saving and reopening the file, I get a
' "Invalid data format" error, and the code for this class module can no longer be
' accessed. Furthermore, no VBA code will run after this happens. Try typing "?1=1"
' into the Immediate Window - you'll get another "Invalid data format" window.
' Alternatively, the error will be "Error accessing file. Network connection may
' have been lost." if the code is changed from using "Me" to "tmp" as noted in the
' comments in DoSomething().
' Steps to replicate:
' 1. Debug > Compile VBAProject.
' 2. Save file.
' 3. Close Excel.
' 4. Reopen file (and may need to open VBE).
Public Sub DoSomething()
' The TypeOf...Is statement seems to be what causes the problem.
' Note that checking "Me" isn't the cause of the problem (merely makes
' for shorter demo code); making a "Dim tmp as Object; set tmp = new Collection"
' and checking "TypeOf tmp Is Child" will cause the same problem.
' Also note, changing this to use TypeName() resolves the issue.
' Another note, moving the TypeOf...Is to a "Private Sub DoSomethingElse()" has
' no effect on the issue. Moving it to a new, unrelated class, however, does
' not cause the issue to occur.
If TypeOf Me Is Child Then
Debug.Print "Parent"
End If
End Sub
子:
Option Explicit
' Class: Child
Implements Parent
Private Sub Parent_DoSomething()
Debug.Print "Child"
End Sub