- PR -

[C#]ExcelでReleaseComObjectのエラー

1
投稿者投稿内容
ともさん
会議室デビュー日: 2007/03/28
投稿数: 9
投稿日時: 2007-11-14 11:52
お世話になります。
VisualStudio2005、Excel2007、C#、WinXP で開発しています。
こちらの過去ログなどを参考にさせていただいて
Excelの操作を行う処理を記載しています。

VSTOで作成したExcelアドインのソースで下記記述を行ったところ、
インタフェースの参照を解放するための
ReleaseComObjectの箇所(※の場所)で例外が発生します。

「"オブジェクトの型は __ComObject か、
 または __ComObject から派生しなければなりません。パラメータ名: o"」

================================================
Excel.Worksheet oParamSht = null;
Excel.Range r = null;
try
{
  try
  {
    // コマンドパラメータワークシートのインタフェース
    oParamSht = (Excel.Worksheet)Wb.Worksheets["パラメータシート"];
  }
  catch
  {
    // 例外エラーメッセージ表示
    return;
  }
  // パラメータ取得
  r = oParamSht.get_Range("B1", Type.Missing);
  string s1 = r.get_Offset(0, 0).Value2.ToString();
  string s2 = r.get_Offset(1, 0).Value2.ToString();
}
catch (Exception ex)
{
  // 例外エラーメッセージ表示
  return;
}
finally
{
  // COMオブジェクト参照カウンタのデクリメント
  if (r != null)
  {
    //※※※※※※※※ここで例外発生
    System.Runtime.InteropServices.Marshal.ReleaseComObject(r);
    r = null;
  }
  if (oParamSht != null)
  {
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oParamSht);
    oParamSht = null;
  }
}
================================================
何らかの参照設定が不足しているのでしょうか????
ソリューションエクスプローラ上では
Microsoft.Office.Core
Microsoft.Office.Interop.Excel
Microsoft.Office.Tools.Common
Microsoft.Office.Tools.Common2007
Accessibility
stdole
Microsoft.VisualStudio.Tools.Applications.Runtime
などを参照設定しております。

とんでもない初歩的ミスをしている可能性大ですが・・
お手数をおかけしますが、よろしくお願いいたします。
ともさん
会議室デビュー日: 2007/03/28
投稿数: 9
投稿日時: 2007-11-14 12:06
上記ソースで
  string s1 = r.get_Offset(0, 0).Value2.ToString();
  string s2 = r.get_Offset(1, 0).Value2.ToString();

get_OffsetはRangeを返却するので
一回参照するごとにReleaseComObjectが必要なことに気付きました。
おかしなソースを乗せてしまい申し訳ありません。
質問した箇所についてはまだ解決していません。
ともさん
会議室デビュー日: 2007/03/28
投稿数: 9
投稿日時: 2007-11-14 13:07
自己レスばかりで申し訳ありません。

別の箇所でReleaseComObjectを使用しても例外が発生していないところがあり、
違いを確認したところ以下のことがわかりました。


例外が発生したのは
自作ExcelAddinのWorkbookOpenイベントメソッド内です。

private void AppEvents_WorkbookOpen(Microsoft.Office.Interop.Excel.Workbook Wb)


パラメータで渡されたWb内を参照しようとしている
Rangeオブジェクトの変数rの型はデバッガ確認したところ以下のように表示されました。

{System.Runtime.Remoting.Proxies.__TransparentProxy}

例外が発生していない箇所では
自前でExcel.Applicationを起動し、セル編集を行っていました。
Rangeオブジェクトの変数は
{System.__ComObject}
と表示されました。


どうやら
{System.Runtime.Remoting.Proxies.__TransparentProxy}
の場合はReleaseComObjectを使用できないということですね。

この場合のオブジェクト解放はどのようにすればよいのでしょうか???
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-11-14 13:42
引用:

ともさんさんの書き込み (2007-11-14 11:52) より:

「"オブジェクトの型は __ComObject か、
 または __ComObject から派生しなければなりません。パラメータ名: o"」


そのままです。 System.__ComObject でないものは ReleaseComObject メソッドで参照カウントをデクリメントする必要がありません。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-11-14 13:43
引用:

ともさんさんの書き込み (2007-11-14 12:06) より:

上記ソースで

  string s1 = r.get_Offset(0, 0).Value2.ToString();
  string s2 = r.get_Offset(1, 0).Value2.ToString();

get_OffsetはRangeを返却するので
一回参照するごとにReleaseComObjectが必要なことに気付きました。


そこだけでなく、

> (Excel.Worksheet)Wb.Worksheets["パラメータシート"];

こちらも Excel.Worksheets で一度参照を取っておかないとダメですね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
ともさん
会議室デビュー日: 2007/03/28
投稿数: 9
投稿日時: 2007-11-14 15:31
じゃんぬねっと さん、どうもありがとうございました!

参照カウントをデクリメントする必要がないということで安心いたしました。
また、Wb.Worksheetsの暗黙の参照部分についてもご指摘ありがとうございました!
1

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