- PR -

VB.NETでエクセルエグゼが残ってしまいます。

投稿者投稿内容
エド
常連さん
会議室デビュー日: 2006/12/07
投稿数: 43
投稿日時: 2006-12-22 09:28
改めて、紙に書いて整理してみた所

@ xlApp = CType(CreateObject("Excel.Application"), Object)
   ↓
  xlApp = CreateObject("Excel.Application")

確かに、無駄な事していました。

A Dim xlSheet As Object = xlSheets.Item(1)
  Dim xlWorksheet [As Object] = xlSheets("Sheet1")
   ↓
  Dim xlSheet As Object = xlSheets.Item(1)
xlSheet = xlSheets("Sheet1")

としてxlWorksheetをなくしました。

B xlSheets("Sheet2").delete()
  xlSheets("Sheet3").delete()
   ↓
  xlSheet = xlSheets("Sheet2")
  xlSheet.delete()
  xlSheet = xlSheets("Sheet3")
  xlSheet.delete()

C xlSheets("Sheet1").range("A" & vliRowsCount + 2 & vlsCol & vliRowsCount + 2).Value = olHairetu
   ↓
  xlSheet = xlSheets("Sheet1")
  xlSheet.range("A" & vliRowsCount + 2 & vlsCol & vliRowsCount + 2).Value = olHairetu

という事でしょうか?☆

最後Cだけ疑問が残るのですが、rangeの所は

  xlRange = xlSheet.range("A" & vliRowsCount + 2 & vlsCol & vliRowsCount + 2)
  xlRange = olHairetu

とするのが正解なのでしょうか?

ひろれい
ぬし
会議室デビュー日: 2006/03/02
投稿数: 486
お住まい・勤務地: 万博開催地
投稿日時: 2006-12-22 10:10
ちょっと気になったので、一言。

ご自分で色々と試してみることはいいことだと思いますが、過去の情報を検索しましたか?
エドさんが悩まれている箇所は、過去の情報を検索すれば出てくると思うのですが。

各言う私も、昔、COM には苦労して投稿しましたから。
(結局、COM は使いませんでしたが・・・)

一度、過去の情報を検索してみることをお薦めします。
エド
常連さん
会議室デビュー日: 2006/12/07
投稿数: 43
投稿日時: 2006-12-22 14:34
解決しました。

C上記の記述の
xlRange = xlSheet.range("A" & vliRowsCount + 2 & vlsCol & vliRowsCount + 2)
xlRange = olHairetu
 ↓
xlRange = xlSheet.range("A" & vliRowsCount + 2 & vlsCol & vliRowsCount + 2)
xlRange.Value = olHairetu

でプロセスの開放が出来ました。

ここでご教授いただいたお陰で、
プロセス開放についてのデバックの仕方
(何処から何処までが開放できていて、何処を通過すると開放できないのか)
を学びました。

また、COMをつかう場合はドットで区切られている部分を
それぞれ分解して変数に格納して使わないといけない事、
またをれを必ず全て開放しなくてはいけない事を学びました。

振り返ってみれば、確かに過去情報を検索してよく見てみれば
同じような事がかかれているとは思いますが、
コロンブスの卵的な感じで分かってしまえば気が付くけれども
何がなんだかわからない状態だと見逃してしまうと言うのが
自分の先の現状だったと思います。

最後にじゃんぬねっとさん、とっちゃんさん、ぽぴ王子さん、ちゃっぴさん、ひろれいさん
それとこの書き込みを閲覧された皆さん、ありがとうございました。

また、より精進を目指して頑張りたいと思います。


じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-12-22 18:27
引用:

エドさんの書き込み (2006-12-22 09:28) より:

(2) Dim xlSheet As Object = xlSheets.Item(1)
  Dim xlWorksheet [As Object] = xlSheets("Sheet1")
   ↓
  Dim xlSheet As Object = xlSheets.Item(1)
xlSheet = xlSheets("Sheet1")

としてxlWorksheetをなくしました。


まだ、おかしいですよね。
無意味なことをしています。

引用:

(3) xlSheets("Sheet2").delete()
  xlSheets("Sheet3").delete()
   ↓
  xlSheet = xlSheets("Sheet2")
  xlSheet.delete()
  xlSheet = xlSheets("Sheet3")
  xlSheet.delete()


同じ変数を利用するならば、参照が上書きされる前に、COM の参照カウントを解放しなければなりません。
このあたりも、いろんなところで散々書いています。

引用:

(4)
  xlSheet = xlSheets("Sheet1")
  xlSheet.range("A" & vliRowsCount + 2 & vlsCol & vliRowsCount + 2).Value = olHairetu


これも、xlSheet を使いまわしているように見えますが、大丈夫でしょうか。

引用:

最後 (4) だけ疑問が残るのですが、rangeの所は

  xlRange = xlSheet.range("A" & vliRowsCount + 2 & vlsCol & vliRowsCount + 2)
  xlRange = olHairetu

とするのが正解なのでしょうか?


いいえ、型を意識しましょう。
文字列型と数値型を & 演算子で結合しない方が良いです。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
エド
常連さん
会議室デビュー日: 2006/12/07
投稿数: 43
投稿日時: 2006-12-28 11:21
アドバイスありがとうございます。

@
Dim xlSheet As Object = xlSheets.Item(1)
xlSheet = xlSheets("Sheet1")
は↓
Dim xlSheet As Object
xlSheet = xlSheets("Sheet1")
ですね★

A
xlSheet = xlSheets("Sheet2")
xlSheet.delete()
xlSheet = xlSheets("Sheet3")
xlSheet.delete()
も↓
xlSheet = xlSheets("Sheet2")
xlSheet.delete()
MRComObject(xlSheet)
xlSheet = xlSheets("Sheet3")
xlSheet.delete()
MRComObject(xlSheet)
と上書きする前に開放すると言う事で問題ないでしょうか?
とすると

B
xlSheet = xlSheets("Sheet1")
xlSheet.range("A" & vliRowsCount + 2 & vlsCol & vliRowsCount + 2).Value = olHairetu
の部分も「xlSheet」に値を代入する前にプロセスを開放して行えば
問題ないという事ですね。

一応、現段階のソースでもプロセスは問題無く開放されている状態ですが、
後学の為にプロセスの開放についてもう一度復習しようと思います。

痒いところに手が届くような親切なアドバイス、
ありがとうございます。

じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-12-28 11:40
引用:

エドさんの書き込み (2006-12-28 11:21) より:

(1)
(snip)
ですね★

(2)
と上書きする前に開放すると言う事で問題ないでしょうか?


はい、参照カウントという意味では問題ないです。
しかしながら、ミスを防ぐためにも別の変数を使用することを強くお勧めします。

引用:

とすると

(3)
xlSheet = xlSheets("Sheet1")
xlSheet.range("A" & vliRowsCount + 2 & vlsCol & vliRowsCount + 2).Value = olHairetu
の部分も「xlSheet」に値を代入する前にプロセスを開放して行えば問題ないという事ですね。


まだ、Excel.Range についての参照が取れていないです。
それと、暗黙の型変換を行って文字列を結合している箇所にも着目して欲しかったです。

引用:

一応、現段階のソースでもプロセスは問題無く開放されている状態ですが、
後学の為にプロセスの開放についてもう一度復習しようと思います。


確かに、オブジェクトによっては、参照カウントを明示的に解放しなくとも、Excel のプロセスは解放されます。
しかし、リソースから解放されるのは、COM ラッパ オブジェクトに対して GC が回収した時になります。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
エド
常連さん
会議室デビュー日: 2006/12/07
投稿数: 43
投稿日時: 2006-12-28 11:51
xlSheet = xlSheets("Sheet1")
xlSheet.range("A" & vliRowsCount + 2 & vlsCol & vliRowsCount + 2).Value = olHairetu

の参照については↓
xlRange = xlSheet.range("A" & vliRowsCount + 2 & vlsCol & vliRowsCount + 2)
xlRange.value = olHairetu

ということですね?
そして、暗黙の型変換という事は
xlRange = xlSheet.range("A" & vliRowsCount + 2 & vlsCol & vliRowsCount + 2)

xlRange = xlSheet.range("A" & Cstr(vliRowsCount + 2) & vlsCol & vliRowsCount + 2)
という事ですね☆
なるほど、全然気が付きませんでした★
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-12-28 11:55
引用:

エドさんの書き込み (2006-12-28 11:51) より:

xlRange = xlSheet.range("A" & vliRowsCount + 2 & vlsCol & vliRowsCount + 2)
xlRange.value = olHairetu

ということですね?


はい、xlRange も解放前に別の参照を入れてしまわないように注意してください。

引用:

そして、暗黙の型変換という事は
xlRange = xlSheet.range("A" & vliRowsCount + 2 & vlsCol & vliRowsCount + 2)

xlRange = xlSheet.range("A" & Cstr(vliRowsCount + 2) & vlsCol & vliRowsCount + 2)
という事ですね☆
なるほど、全然気が付きませんでした★


まだ、気付いていない箇所があるようですよ。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌

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