じゃんぬねっと日誌

ネタと雑記と時々プログラミング

目次

Blog 利用状況

ニュース

不況すぎる件。

スポンサードリンク

運営サイト

  • C# と VB.NET の入門サイト

書庫

Excel、COM、解放、参照カウント、デクリメント...

某所にて、

じゃんぬさーん、出番ですよーw

などと、書かれてしまったので、徐に検索。

@IT 会議室 検索結果
http://www.atmarkit.co.jp/bbs/phpBB/search.php?term=Excel+COM&search_user_id=212989...

Σ(;゚Д゚) ご、ごめんなさい!!
確かに、くどいほど書いているみたいですね。(;^-^)

ただ、この問題は放置すると障害になりますから、私もある程度はフォローしたいのですね。
(この問題に関しては、渋木宏明(ひどり) さんも、くどい部類に入るんじゃないでしょうかww)

過去にあるものは、過去ログを見るように書いてはいますが、最近は、「過去ログを見てもわからなかった」系も多いので、「解放漏れは、どんな時に起きるのか?」というような、反面記事が必要なのだと感じています。

本回答のために「COM オブジェクトを解放する」という Tips を書きましたが、あの記事では、適正を持っていないと (?) 'どんな時に解放漏れが起きるのか' が、わからない (?) みたいです。
(連続したオブジェクトへのパス、コレクションから要素を取り出す時、だけ注意するだけなのですけどね...)

私の場合、どうしても使いたい場合は、VSTO か VBA 側のマクロで対応するでしょう。
帳票であれば、ActiveReports か、CrystalReports を使います。

データを吐き出したいだけなのであれば「書式」なんて必要ないですから、CSV ファイルを使います。
CSV ファイルならばテキスト ベースなので Excel とは直接は関係しません。(CsvReader クラスを作ってウマーですw)

投稿日時 : 2006年7月25日 9:50

コメントを追加

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/25 10:06 じゃんぬ

後半を見ればわかるかとは思いますが、COM の使用は薦めていません。
むしろ、.NET Framework 系の言語ではやめましょう派です。

私自身は、COM Interop 系統を、"業務で" 使ったことはなかったりします。
というより、.NET Framework 系は、業務では 3 ヶ月程度しかやってないし... orz
MVP for C# なのに、C# を業務で使ったことがないし... orz orz

もう、VB6 とか VC6 とか Delphi はおなかいっぱいです。
Java か、.NET Framework 系の仕事をください。
むしろ、私の仕事と交換してください!! (w

orz

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/25 12:01 張本人

某所にて、

>じゃんぬさーん、出番ですよーw

などと、書いてしまった張本人です。
申し訳ありませんでしたm(_ _)m

でも、質問があると当然最初にググるわけですが、どれを見てもじゃんぬさんが絡んでいるんですよねぇ

じゃんぬさんの地域なら、Javaの仕事はいっぱいあるのでは?
あの1兆円企業さんが導入してますから・・・

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/25 12:14 じゃんぬ

>ひ○れい さん
いえ、元よりネタだと認識しております (この記事もw) ので、気にはしておりません。
確かに、ここ 1 年のスレッドは私が絡んでいるものが多いと思います。orz

> じゃんぬさんの地域なら、Javaの仕事はいっぱいあるのでは?
> あの1兆円企業さんが導入してますから・・・

1 兆円企業ってどこでしょう...? (w
たとえばですが、ト○タ絡みの仕事は、組込制御くらいしかやっていませんね。
いや、ア○シン関係と言った方が良いのかもしれません。

Java は、コニ○ミノ○タ関係でもごもご(ry
目○とか、み○そだと、ほとんど VB だったりします。
S○○Y も、C とか VB が多いですね。(画像処理関係だとほとんど C ですが)
さらに、不○痛あたりだと、COBOL とかもまだあるんですよね... orz

○○ソフ○あ○しで、.NET 系の案件はチラホラ出ていますが、
採算が取れないので、外注さんに出しております。
あ、これがいけないのか!

# 伏字でもバレバレw

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/25 12:57 ○ろれい

>1 兆円企業ってどこでしょう...? (w

○ヨタですw
前の会社にいる時に、Javaの案件がありました。私は、COBOLでしたが・・・

○イシンやデ○ソーとかだと、確かに組込系ばっかですね。
他のシステムは、それぞれ持ってる関係会社が担当してるみたいです。保守の問題ですかね。

>目○とか、み○そだと、ほとんど VB だったりします。
>S○○Y も、C とか VB が多いですね。(画像処理関係だとほとんど C ですが)

この地方でも、VB案件はまだまだ多いですね。
なぜか、.NETは避けられてます。どうしてなんでしょうか・・・
今から新規開発なら、VB6より.NETだと思うんですが・・・
開発コストの問題かなぁ

>さらに、不○痛あたりだと、COBOL とかもまだあるんですよね... orz

N や T でも多いですよ。
やれる人がいないので、おじさんばかりのPJとなりますねw

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/25 14:08 NyaRuRu

折角なのでクイズでも.
全問正解でも何も出ませんけど.

問題1
「COM オブジェクトを解放する」(http://jeanne.wankuma.com/tips/programing/releasecom.html) にあるようなコードで,Excel 表示中にもとの .NET アプリケーションを強制終了するとどうなるでしょう?
1) Finally 句が実行されるので Excel プロセスも消滅する
2) Finally 句が実行されないが,ファイナライザが実行されるので Excel プロセスは消滅する
3) Finally 句は実行されず,ファイナライザも実行されないが,OS が Excel プロセスも殺してくれる
4) Finally 句は実行されず,ファイナライザも実行されず,Excel プロセスは残る

問題2
Internet Explorer で Excel ファイルを開くと,同様に 裏で Excel プロセスが起動していますが,このとき Internet Explorer を強制終了するとどうなるでしょう?
1) OS が Excel プロセスも殺してくれる
2) Excel プロセスは残る

まあ順番的には問題2が基礎で問題1が応用かな?

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/25 14:28 はいこーん

これ実は問題1の方が簡単かな。
だって、Excel表示中って書いてあるし。
(Application.Quitを実行していないのだから、勝手にプロセスが解放されるわけがない)

とりあえず、Quitしてないと話にならないと思う。

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/25 14:34 NyaRuRu

>(Application.Quitを実行していないのだから、勝手にプロセスが解放されるわけがない)

んー,でも xlApplication.Quit は

>どんな状況でも (例外が発生しても) 安全に解放するには、try ~ finally を多用します。

の finally の中に書いてありますぜ?

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/25 14:57 はいこーん

> の finally の中に書いてありますぜ?

どんな状況でもは御幣があるだけのこと。
強制終了を除いたイレギュラーという意味だと思う。
ま、言葉遊びみたいなものだね。

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/25 15:01 はいこーん

そういう意味だと、Thread内の場合もダメだろうね。
ありゃ誤解を招くから直した方がいいような気がするなあ。

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/25 15:12 じゃんぬ

うーん、finally 句については、そういう次元で書いたつもりはなく、
実行されないケースについても十分承知しているわけで...

たとえにしても、極端ですが、

  try {
    System.Diagnostics.Process.GetCurrentProcess().Kill();
  } finally {
    System.Console.WriteLine("実行されるわけもなく")
  }

なんてコードを実行しても、finally 句は当然実行されません。

ttp://dobon.net/cgi-bin/tipsrate/vote.cgi?mode=v&id=beginner/tryfinally.html

# 直しておこうかな。

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/25 15:37 NyaRuRu

>ま、言葉遊びみたいなものだね。

ま,確かにそうなんですけどね.
この辺でも書きましたが,実際のとこかなりの部分でOSのリソース回収に救われている面は多いと思っています.
http://d.hatena.ne.jp/NyaRuRu/20060605/p1#c

例えばVisualStudioで開発するときに,F5でデバッグ起動してShift+F5で終了するだけで強制終了扱いなんですが,こういうのでファイルハンドルとかGDIハンドルがリークしてたら開発作業自体大変ですからね.
Shift+F5で終了するときはusingもfinallyもファイナライザも無力ですよと.

一方COMのアウトプロセスサーバで「きちんと解放しましょうね」が連呼されるのは,結局のところOSが面倒見てくれないのでミスが目立ちやすいからです.
じゃあ「きちんと解放すれば大丈夫か」というと,やっぱり強制終了などで残ることもあると.
「きちんと解放するプログラム = 良いプログラム」という図式では,この問題を完全に解決できないことが伝わらず,「参照カウントを解放しさえすればよい」という考えが広がらないかな,というのを若干懸念しています.

サーバサイドなどで,プロセスのリークを気にするなら,むしろプロセス監視サービスを作った方が直接的じゃないかと思ったり.

まあ普通の人がそこまで知っている必要もないとは思いますけどね.

>そういう意味だと、Thread内の場合もダメだろうね。

変なタイミングで ThreadAbortException が発生して,動作がスキップされるとまずいかもしれませんね.

とはいえ,finally 句中のスレッドに対しては Abort がブロックされるといった話もあって,可能性を読み切るのは結構大変ですけど.
http://d.hatena.ne.jp/NyaRuRu/20060531#p1
http://d.hatena.ne.jp/NyaRuRu/20060602#p1

ちなみに ThreadAbortException を含む非同期例外に対しては,C# のusing 構文や lock 構文は「完全」ではありません,というのが先ほどのこの話です.
http://d.hatena.ne.jp/NyaRuRu/20060605#p1

というわけで,.NET の中で閉じていてすら,「どんな状況でも」は結構難しかったりするんですな.
まあ雑学としてご参考までに,と.

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/25 18:24 しばえび

じゃんぬさん、あちこちで参考にさせて頂いてます。この場を借りてお礼申し上げます。
特に「COM オブジェクトを解放する」のお陰で、何がNGなのかという基礎は理解できました。
最近は、大ポカしない限り、解放漏れを起こす事もなくなりました。
.NET C#からExcelをいじることになった時、最初にここを教えて貰ったのは、本当にラッキー
だったと思います(出入りしてる方も皆さん博識だし)。

今やってることは、「SQLServer→Excel/CSV→Excel/Text→Excel/Excel→Excel」。
「Excel→Excel」は激しく抵抗したんですが、負けました。
特定列の項目が条件にヒットする時は、別の列の項目の色を変える、と指定された時は、
「よりにもよって行判定ですかぃ!!!」
と本気で凹みました。
回避策を発見したので、行判定だけはせずに済みましたが、行ループが一番遅いんですよね。

> 私の場合、どうしても使いたい場合は、VSTO か VBA 側のマクロで対応するでしょう。
> 帳票であれば、ActiveReports か、CrystalReports を使います。

VSTO欲しいなーと呟いてみたものの、NGでした。(^^;
また、現行で使用しているファイルがExcelなので、あくまでもExcelに拘ってくれます。
結局、予算と政治に負けまくりです。

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/26 0:10 アクア

いつもお世話になっております。
私は現在VisualStudio2005 へのアップグレード版の購入を考えているのですが、
Professional EditionにしようかTool for Officeにしようか悩んでいます。

中博俊さんの本を元にC++の勉強もしてみたいし、一方でExcelなどOfficeとの連動Applicationも作ってみたいし…
あぁ悩む…。(ポインタは難しそうだからC#でもいいかな?とか)

じゃんぬさんのサイトや花ちゃんさんのサイトはCOM参照の解放で勉強させていただきました。
いや、勉強したつもりでしたが、NyaRuRuさんの問題に自信をもって答えられませんでした。

ムムム…う~ん…自分のスキルがまだまだだということは検証できた。w

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/26 0:57 ちゃっぴ

>
(Application.Quitを実行していないのだから、勝手にプロセスが解放されるわけがない)

と思っているあなたへ。

Set objExcel = CreateObject("Excel.Application")

を VBS で実行してみましょう。

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/26 6:33 ちゃっぴ

> だって、Excel表示中って書いてあるし。

と書いてあるのを見逃していた。

まあ、こじつけになりますが、こういうのもあります。

Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
Set objWorkBook = objExcel.WorkBooks.Add
objExcel.ActiveCell.Value = "hoge"
objWorkBook.Saved = True
objWorkBook.Close
objExcel.UserControl = False

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/26 9:49 はいこーん

また言葉尻をつかまえての意見か。
VBSの話題なんてしてないだろうに。

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/26 13:11 NyaRuRu

>VBS

COM と相性の良い ActiveScript を使うのは十分有りだと思いますけどね.
.NET から finally 山のように重ねて書くよりはむしろ正攻法な気がしてたり.

--------------------------------------
参照設定
・"Microsoft Excel 11.0 Object Library"
・"Microsoft Script Control 1.0"

using System;
using System.Collections.Generic;
using System.Text;
using MSScriptControl;
using Excel = Microsoft.Office.Interop.Excel;
using System.Threading;
using System.Runtime.InteropServices;

class Program
{
static void Main(string[] args)
{
List<object> rcws = new List<object>();

try
{
ScriptControl scl = new ScriptControl();
rcws.Add(scl);
Excel.Application excel = new Excel.Application();
rcws.Add(excel);

scl.Language = "VBScript";
scl.AddObject("objExcel", excel, false);
scl.ExecuteStatement("objExcel.Visible = True");
scl.ExecuteStatement("Set objWorkBook = objExcel.WorkBooks.Add");
scl.ExecuteStatement("objExcel.ActiveCell.Value = \"hoge\"");
scl.ExecuteStatement("objWorkBook.Saved = True");
scl.ExecuteStatement("objWorkBook.Close");
scl.ExecuteStatement("objExcel.UserControl = False");
Thread.Sleep(1000);
}
finally
{
foreach (object obj in rcws)
{
try
{
Marshal.ReleaseComObject(obj);
}
catch
{
}
}
}
}
}

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/26 13:43 はいこーん

なるほろ。こりゃいいですな。
コンパイルチェックできるようにかけたらサイコーだけど、そこまでする必要があるものでもないか。

# re: Excel、COM、解放、参照カウント、デクリメント... 2006/07/26 13:46 はいこーん

COMと相性の良いという意味では、その部分だけVB6で作成してそれを実行させるって方が綺麗かもしれない。
Excelのマクロに直接書いて実行させるのもありかな。(ちょっとCOMの記述を.NET側でしなきゃいけないけど)

# [.NET]COM Interop, Marshal.ReleaseComObject 2006/07/27 17:41 NyaRuRuの日記

「じゃんぬねっと日誌」より. Excel、COM、解放、参照カウント、デクリメント... コメント欄でちょこっと書きましたが,C# から COM の参照カウントを扱うのが面倒なら,自動コード生成を行ったり,参照カウント向きの言語*1を併用したりするのがむしろ正攻法かと思います

タイトル  
名前  
URL
コメント