- PR -

C# Excelマクロの削除

投稿者投稿内容
もも
常連さん
会議室デビュー日: 2005/07/25
投稿数: 46
投稿日時: 2005-10-28 18:28
いつもお世話になっています。

じゃんぬねっとさまのコードを参考にコードし(「Microsoft.Vbe.Interop.VBProject」の部部でコンパイルエラーになってしまったので、「VBIDE.VBProject」に変更しました)試したところ、3回目でアプリケーションエラーになってしまいました・・・
「VBIDE」を使用したのが、問題あるのでしょうか・・・・
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-28 18:33
引用:

ももさんの書き込み (2005-10-28 18:28) より:

「VBIDE」を使用したのが、問題あるのでしょうか・・・・


Office のバージョンはいくつですか?
(Microsoft Excel Object Library はいくつのバージョンは使用していますか?)

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
もも
常連さん
会議室デビュー日: 2005/07/25
投稿数: 46
投稿日時: 2005-10-28 18:39
いつもお世話になっています。

Office のバージョンはいくつですか?
 ⇒Officeのバージョンは、(9.0.2812)です。
  XPのバージョンも同じです・・・・・

Microsoft Excel Object Library はいくつのバージョンは使用していますか?
 ⇒9.0を使用しています。
もも
常連さん
会議室デビュー日: 2005/07/25
投稿数: 46
投稿日時: 2005-10-28 19:56
よく分からないのですが、エラーがでなくなりました。

コード

try
{
 VBIDE.VBProject vbProject = this._xlBook.VBProject;
 try
 {
  VBIDE.VBComponents vbComponents = vbProject.VBComponents;
  try
  {
   // マクロの削除
   VBIDE.VBComponent vbComponent = vbComponents.Item("Module1");
   vbComponents.Remove(vbComponent);
   System.Runtime.InteropServices.Marshal.ReleaseComObject(vbComponent);
  }
  finally
  {
   if(vbComponents != null)
   {
     System.Runtime.InteropServices.Marshal.ReleaseComObjectvbComponents);
   }
  }
 }
 finally
 {
  if (vbProject != null)
  {
   System.Runtime.InteropServices.Marshal.ReleaseComObject(vbProject);
  }
 }
}
finally
{
}

です。VBIDE.VBComponentのTypeを参照したりすると、アプリケーションエラーが発生します。ステップ実行せずに動作させると、エラーにはなりませんが、ステップ実行し
「vbComponents.Remove(vbComponent);」にステップ実行の黄色いラインがきたとき、
ウォッチで、「vbComponent」の内容を確認すると、アプリケーションエラーが起こりました。
「vbComponent」の内容さえみなければ、エラーは起きないようです。

なんだか、気持ちが悪い結果となりましたが、じゃんぬねっとさま、数々の助言、投稿、
本当にありがとうございました。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-28 20:01
引用:

ももさんの書き込み (2005-10-28 19:56) より:

VBIDE.VBComponentのTypeを参照したりすると、アプリケーションエラーが発生します。ステップ実行せずに動作させると、エラーにはなりませんが、ステップ実行し
「vbComponents.Remove(vbComponent);」にステップ実行の黄色いラインがきたとき、
ウォッチで、「vbComponent」の内容を確認すると、アプリケーションエラーが起こりました。
「vbComponent」の内容さえみなければ、エラーは起きないようです。


変ですね。
Type プロパティなんて参照カウントには含まれないように思えますし、
foreach で列挙していくタイミングで何かが起きていると予想していました。

私は Office 2003 を使っていますが問題なく動いていました。
(セキュリティを低くしないとマクロが削除できないようでしたが)

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
もも
常連さん
会議室デビュー日: 2005/07/25
投稿数: 46
投稿日時: 2005-10-28 20:14
すこしづつコメントをはずし、確認していきました。
そしたら、foreachで、
コード
 foreach (VBIDE.VBComponent vbComponent in vbComponents)
{
   System.Runtime.InteropServices.Marshal.ReleaseComObject(vbComponent);
}
としても、アプリケーションエラーがでました。
foreachの際、「vbComponent」の中身をどうやら、参照しているようです。(かなり憶測ですけど・・・)

 Windows2000 Excel2000でしか、起きない現象なのかもしれません。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-28 20:26
ももさん、情報ありがとうございます。

引用:

ももさんの書き込み (2005-10-28 20:14) より:

foreachの際、「vbComponent」の中身をどうやら、参照しているようです。
(かなり憶測ですけど・・・)


そうかもしれません。
foreach ではなく for に置き換えてひとつずつ参照を取って試して頂けませんでしょうか?
これは、私の勝手なお願いですので、気が向いたらで結構です。
とりあえず、コードも作っておきます。

コード:

// VBA なので要素は 1 から始まるんでしたっけ?
for (int i = 1; i <= vbComponents.Count; i++) {
    VBIDE.VBComponent vbComponent = null;

    try {
        vbComponent = vbComponents.Item(i);
        //vbComponent.Remove();
    } finally {
        System.Runtime.InteropServices.Marshal.ReleaseComObject(vbComponent);
    }
}


これでも起きるようでしたら、vbComponents を直接扱ってみてください。
しかし、vbComponents(i).Remove という感じで直接やるのは参照カウントが残り、
Excel が正常に終了しなくなるような恐れがありますが...

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
もも
常連さん
会議室デビュー日: 2005/07/25
投稿数: 46
投稿日時: 2005-11-01 10:31
じゃんぬねっとさま 返信遅くなってすみません。

じゃんぬねっとさまが作成したコードを試してみましたが、アプリケーションエラー
起こりませんでした。

やっぱり「foreach」がネックでしたね。

私が最初に記述した
_xlBook.VBProject.VBComponents.Remove(xlBook.VBProject.VBComponents.Item("Module1"));
は、ご指摘通り、開放処理がされていないことが、エラーが起きていた原因のようですね。
COMは、難しいですね。

スキルアップ/キャリアアップ(JOB@IT)