- PR -

C# Excelマクロの削除

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

今不思議な現象で困っています。
C#のコードから、Excelファイル内にあるマクロを下記コードで削除し、Excelファイルを
保存後、他の処理(例えばメッセージボックス表示など)を行うと、
Excelのアプリケーションエラーが起きてしまいます。(赤×のダイアログがでます。)

コード-------------------------------------------------------------
foreach(VBIDE.VBComponent vb in xlBook.VBProject.VBComponents)
{
 // Macroシートのみ削除する
 if(vb.Type == VBIDE.vbext_ComponentType.vbext_ct_StdModule)
 {
  xlBook.VBProject.VBComponents.Remove(vb);
 }
}

または、
_xlBook.VBProject.VBComponents.Remove(xlBook.VBProject.VBComponents.Item("Module1"));
-------------------------------------------------------------------
 
しかし、WinXPでは、アプリケーションエラーにはならず、Win2000で現象がでます。
OSのバグなのでしょうか。(そんなことはないと思うのですが・・・)

ちなみに、Win2000はSP4です。

今回のプログラムはウィンドウアプリです。

ささいなヒントでも構いません。どなたかご教授願えませんでしょうか。
もも
常連さん
会議室デビュー日: 2005/07/25
投稿数: 46
投稿日時: 2005-10-28 16:25
追記です・・・

OSに依存するかどうかを確認するために、他の言語で確認してみました。
結果は
 VB.Net ・・・ アプリケーションエラーが起きる
 VB6.0  ・・・ エラーが起きない
 VC++6.0 ・・・ エラーが起きない

以上の結果より、.Netでエクセルマクロを削除すると、アプリケーション
エラーが起きることが分かりました。

最終手段としては、VC++6.0で作成したDLLをCallするようにするつもり
ではいますが、できれば、C#で出来ればと考えております。

思い当たる節などがありましたら、ご教授、よろしくお願いします・・・
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-28 16:43
Office のバージョンは XP も 2000 も同じなのでしょうか?
VBIDE.VBComponent は、Microsoft.Vbe.VBComponent でしょうか?
マクロを削除しなかった場合には現象は再現しないのでしょうか?
COM オブジェクトの解放は適切でしょうか?

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
もも
常連さん
会議室デビュー日: 2005/07/25
投稿数: 46
投稿日時: 2005-10-28 17:01
じゃんぬねっとさま、返信ありがとうございます。

Office のバージョンは XP も 2000 も同じなのでしょうか?
 ⇒Officeのバージョンは、2000、XPともに同じです。

VBIDE.VBComponent は、Microsoft.Vbe.VBComponent でしょうか?
 ⇒参照の追加で Excel9.0オブジェクトライブラリを追加した際に、使えるようになったので、「Microsoft.Vbe.VBComponent」であると思います。

COM オブジェクトの解放は適切でしょうか?
 ⇒Excelマクロを削除するコードをコメントアウトし、実行すると、アプリケーションエラー
は起きません。タスクマネージャーなどで、確認したところ、Excelは終了しているもようです。しかし、Excelマクロを削除し、アプリケーションエラーになった際は、タスクマネージャーにExcelが残っています。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-28 17:16
質問の返答ありがとうございました。

引用:

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

Excelマクロを削除するコードをコメントアウトし、実行すると、アプリケーションエラーは起きません。
タスクマネージャーなどで、確認したところ、Excelは終了しているもようです。しかし、Excelマクロを削除し、アプリケーションエラーになった際は、タスクマネージャーにExcelが残っています。


まあ、強制終了した場合は解放されませんからね。
ただ、

引用:

コード:
    foreach(VBIDE.VBComponent vb in xlBook.VBProject.VBComponents)
    { 
        // Macroシートのみ削除する 
        if (vb.Type == VBIDE.vbext_ComponentType.vbext_ct_StdModule)
        {
            xlBook.VBProject.VBComponents.Remove(vb);
        }
    }



こちらでは何も解放していませんよね...

# ちょっと私もこれから試してみようかと思います。
# しばしお待ちを...

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
もも
常連さん
会議室デビュー日: 2005/07/25
投稿数: 46
投稿日時: 2005-10-28 17:23
じゃんぬねっとさま ありがとうございます。

じゃんぬねっとさまのHPを拝見させていただき、作成したVB.Netのソースを記載します。

コード

Dim xlApp As Excel.Application
Dim xlBook As Excel.Workbook

 Try
  xlApp = New Excel.Application
  Try
   xlBook = xlApp.Workbooks.Open("C:\\\\Macro.xls")
   xlBook.VBProject.VBComponents.Remove(xlBook.VBProject.VBComponents.Item("Module1"))
   xlBook.Saved = False
   xlApp.DisplayAlerts = False
   xlBook.Close(True, "C:\\\\a.xls")
  Finally
   If Not xlBook Is Nothing Then
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
   End If
   xlBook = Nothing
  End Try
  xlApp.Quit()
 Finally
  If Not xlApp Is Nothing Then
   System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
  End If
  xlApp = Nothing
 End Try

 GC.Collect()

1、2度では、アプリケーションエラーにはならず、何度も実行するとエラーが起きてしまいます・・・・
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-28 17:58
実行してみましたが、問題はなさそうでした。
相変わらず、try 〜 finally の嵐ですが... (これだから COM は嫌いです)

コード:

private void button1_Click(object sender, System.EventArgs e) {
    // 必要な変数は try の外で宣言する
    Excel.Application xlApp = null;

    // COM オブジェクトの解放を保証するために try 〜 finally を使用する
    try {
        xlApp = new Excel.Application();
        xlApp.DisplayAlerts = false;
        Excel.Workbooks xlBooks = xlApp.Workbooks;

        try {
            Excel.Workbook xlBook = xlBooks.Open(
                @"C:\マクロ付き稼動報告書.xls",
                System.Reflection.Missing.Value, System.Reflection.Missing.Value,
                System.Reflection.Missing.Value, System.Reflection.Missing.Value,
                System.Reflection.Missing.Value, System.Reflection.Missing.Value,
                System.Reflection.Missing.Value, System.Reflection.Missing.Value,
                System.Reflection.Missing.Value, System.Reflection.Missing.Value,
                System.Reflection.Missing.Value, System.Reflection.Missing.Value,
                System.Reflection.Missing.Value, System.Reflection.Missing.Value
            );

            try {
                Microsoft.Vbe.Interop.VBProject vbProject = xlBook.VBProject;

                try {
                    Microsoft.Vbe.Interop.VBComponents vbComponents = vbProject.VBComponents;

                    try {
                        foreach (Microsoft.Vbe.Interop.VBComponent vbComponent in vbComponents) {
                            try {
                                if (vbComponent.Type == Microsoft.Vbe.Interop.vbext_ComponentType.vbext_ct_StdModule) {
                                    vbComponents.Remove(vbComponent);
                                }
                            } finally {
                                if (vbComponent != null) {
                                    System.Runtime.InteropServices.Marshal.ReleaseComObject(vbComponent);
                                }
                            }
                        }
                    } finally {
                        if (vbComponents != null) {
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(vbComponents);
                        }
                    }
                } finally {
                    if (vbProject != null) {
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(vbProject);
                    }
                }

                xlBook.Save();
                MessageBox.Show("保存しました!");
            } finally {
                try {
                    xlBook.Close(System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
                } finally {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook);
                }
            }
        } finally {
            if (xlBooks != null) {
                try {
                    xlBooks.Close();
                } finally {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks);
                }
            }
        }
    } finally {
        try {
            xlApp.Quit();
        } finally {
            System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
        }
    }
}


あー疲れました。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
もも
常連さん
会議室デビュー日: 2005/07/25
投稿数: 46
投稿日時: 2005-10-28 18:07
じゃんぬねっとさま ありがとうございます。

早速試させていただきます。
何度も、親切にありがとうございました。

結果を後ほど、報告させていただきます。

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