こんばんは,いつも勉強させていただいております.
どうぞよろしくお願いいたします.
毎夜寝ずに.NETプログラミングでエクセルが動くのを楽しんでおりますが,
手元の参考書とネット検索だけではすっきりしない疑問点が数点あります.
どれか一つでもアドバイスいただけると非常に嬉しいです.
もしお詳しい方がいらっしゃいましたら,どうぞお願いいたします.
「.」が沢山あるような深いプロパティ等を使いたい際(たとえばエクセルの
シート上にグラフが数個あり,これらの軸ラベルを変更するとき)
xlSheet.ChartObject.Chart.Axes(1).Axistitle.text = "test"
といきなり書くと解放できなくなると思うのですが,
(1)この一行を書くためだけに,すべての階層のObjectを作成・解放するものなのでしょうか???
一応動作はするのですが,あまりこんな書き方を見かけないのですが.....
Dim ChartObject As Object
Dim ChartObjects = xlSheet.ChartObjects
For Each ChartObject In ChartObjects
ChartObject.Activate()
Dim myChart As Object = ChartObject.Chart
Dim myAxes As Object = myChart.Axes
Dim myAxis1title As Object = myAxes(1).Axistitle
Dim myAxis2title As Object = myAxes(2).Axistitle
myAxis1title.text = "test"
myAxis2title.text = "test"
MRComObject(myAxis2title) : myAxis2title = Nothing
MRComObject(myAxis1title) : myAxis1title = Nothing
MRComObject(myChart) : myChart = Nothing
MRComObject(myAxes) : myAxes = Nothing
MRComObject(ChartObject) : ChartObject = Nothing
Next
MRComObject(ChartObjects) : ChartObjects = Nothing
(2)解放の順序については,下の階層からすべき? みたいなルールは特に無いのでしょうか.
'たとえば↓みたいに下の階層から解放するか,
MRComObject(myAxis1title) : myAxis1title = Nothing
MRComObject(myAxes) : myAxes = Nothing
MRComObject(myChart) : myChart = Nothing
'もしくは↓みたいに上の階層から解放するか
MRComObject(myAxis1title) : myAxis1title = Nothing
MRComObject(myAxes) : myAxes = Nothing
MRComObject(myChart) : myChart = Nothing
(3)下のコードだとぜんぜん問題ないんですが,
Dim ChartObject As Object
Dim ChartObjects = xlSheet.ChartObjects
MRComObject(ChartObject) : ChartObject = Nothing
MRComObject(ChartObjects) : ChartObjects = Nothing
次のようにFor,Nextを入れるだけでExcelが解放されなくなります.
Dim ChartObject As Object
Dim ChartObjects = xlSheet.ChartObjects
For Each ChartObject In ChartObjects
MRComObject(ChartObject) : ChartObject = Nothing
Next
MRComObject(ChartObjects) : ChartObjects = Nothing
この現象に一番困っております.もし何かお気づきになることがございましたら,
是非ともアドバイスしてやってください.
(4)Excel解放のタイミングが,同じプログラム実行時でも弱冠異なるのですが,
これはよくある現象なのでしょうか?それともコーディングに問題が???
たとえば,
Excel操作 →解放 →msgbox("終わり")
としたときに,メッセージボックスのOKをわざと押さずに待機していると
OKを押すまでExcel.Exeが解放されない時もあれば,押す前に一瞬で消える時もあります.
どれか一つでもアドバイスいただけるようでしたら,是非よろしくお願いします.
また上記コードの書き方に何か些細な突っ込みでもございましたら,いただければ嬉しいです.
なにとぞお願いいたします.
No.1ベストアンサー
- 回答日時:
>(1)この一行を書くためだけに,すべての階層のObjectを作成・解放するものなのでしょうか???
一応動作はするのですが,あまりこんな書き方を見かけないのですが.....
そういうものだと思います。
VB6のときのほうが簡単でしたよね。
Vistual Studio Office Editionのような名前のものを使ってください。
>(2)解放の順序については,下の階層からすべき? みたいなルールは特に無いのでしょうか.
もちろんです。
下から開放しなければ、MRComObjectが開放対象を正しく特定できません。
>3)下のコードだとぜんぜん問題ないんですが,
Dim xlApp As Object = CreateObject("Excel.Application")
Dim xlBooks As Object = xlApp.Workbooks
Dim xlBook As Object = xlBooks.Open(ExcelPath)
Dim xlSheets As Object = xlBook.Worksheets
Dim flg As Short = 0
For Each sht As Object In xlSheets
MRComObject(sht)
Next
MRComObject(xlSheets) 'xlSheets の解放
Try
xlBook.Save()
xlBook.Close(False) 'xlBook を閉じる
Catch ex As Exception
End Try
MRComObject(xlBook) 'xlBook の解放
MRComObject(xlBooks) 'xlBooks の解放
xlApp.Quit() 'Excelを閉じる
MRComObject(xlApp) 'xlApp を解放
ちゃんと消えます。
sheetから書くと、bookあたりが自動的に?作られてしまうのではないでしょうか?
>(4)Excel解放のタイミングが,同じプログラム実行時でも弱冠異なるのですが・・・
どうでしょうか?
さほど大きくづれることはないはずです。
AKARI0418 様
どうもありがとうございます.なんとすべての質問にご回答いただけますとは.
ご親切にどうもありがとうございます.
>(1)
>そういうものだと思います。
>VB6のときのほうが簡単でしたよね。
一発ですっきりしました.どうもありがとうございます.
VB6は触ったことがございません...VB6のコードを拾ってきて
.NETに直せないことはたまにございますが...
ずっとFortranオンリーで,何週間も数値計算して数字の羅列を吐き出すのが
この世のプログラムのすべてと思い込んでおりましたが,
.NETに始めて触れて取りつかれて毎晩ワクワクいるヘタレでございます.
あまりこういう書き方に触れたことがないということは
まだまだ修行と検索量が足りないのかもしれませんね.
どうもありがとうございます.
>(2)
>もちろんです。
>下から開放しなければ、
どうもありがとうございます.すっきりしました.
ネットで必死に検索をかけておりますと,たまにxlAppから
解放しているコードを見かけますので,????と.
お詳しい方にアドバイスいただけて良かったです.
>(3)
コードでご確認までいただきどうもありがとうございます.
ご指摘いただいた通り,sheetあたりの宣言文をもう少し練ってみます.
どうもありがとうございます.
>(4)さほど大きくづれることはないはずです。
ご回答をいただいてから考えておりましたが,どうも私の
コーディングが下手なせいでもともと解放されにくいプログラムを
実行したときに発生している現象のようでございます.
おそらくきちんとしたコードの場合はAKARI0418様のおっしゃる通りに
なるのだと.というかなるはずですよね.
ご親切に沢山のアドバイスをいただけて助かります.
本当にどうもありがとうございました.
No.3
- 回答日時:
参考になると思います。
http://hanatyan.sakura.ne.jp/dotnet/Excel03.htm
きちんとすべての対象にReleaseComObjectを呼んでいるのであれば、
GC.Collect()は必要ないはずです。
GC.Collect()を行わなければ、EXCELが残ってしまうというのは、開放もれがあるはずです。
クラスを経由して行っている場合はその親クラスにあたるインスタンスに対しても、ReleaseComObjectが必要です。
むやみにガベージコレクタに対して、Collectを発行するべきではありません。
GCはジェネレーション管理を行っており、Collectにより世代がどんどん増えていってしまい負荷がかかります。
http://www.atmarkit.co.jp/fdotnet/dotnettips/021 …
AKARI0418 様
ご親切にどうもありがとうございます.
自分のコードをすべて,リンクしていただいたページの書き方に直したところ
コードの半分が解放できました.どうもありがとうございます.
自分の思い込みで勝手に解放できないように修正してしまっていたようです.
今までは,質問文にかかせていただいたような
Dim xlSheet As Excel.Worksheet
Dim ChartObject As Object
Dim ChartObjects = xlSheet.ChartObjects
For Each ChartObject In ChartObjects
Dim myChart As Object = ChartObject.Chart
Dim myAxes As Object = myChart.Axes
Dim myAxis1title As Object = myAxes(1).Axistitle
という書き方をしておりましたのを,花ちゃんのようにExcel.Axisとして解放されました.
Dim MyAxis As Excel.Axis
Dim MyAxes As Excel.Axes
MyAxes = MyChart.Axes
For Each MyAxis In MyAxes
何故か前者のような書き方でも解放されている個所もありますが,
すべて後者に直しました.
以前参考書か何かで「コードの途中でExcel.~と書くと知らないうちに2つ目の
Applicationオブジェクトを参照して~解放できなくなる.」というのを
読んだ覚えがありまして,コードをすべて前者のように書き換えておりましたのが原因のようです.
ブラウザの履歴にも残っておりましたが,まったく目が届いておりませんでした.
非常に沢山のアドバイスをいただきどうもありがとうございました.
現時点でもまだ解放できない部分がありますが,おそらく別の要因だと思われるので,
また別スレッドで質問させていただきます.
本当にご親切にどうもありがとうございました.
No.2
- 回答日時:
そのプロシージャから抜ける段階で
GC.Collect()
を実行してみましょう
これの実行で参照の開放を忘れていなければプロシージャを抜けた段階でExcelのタスクは消滅するようですよ
単純に workbooksコレクションを取得し開放しただけでも
Exeが実行中はExcelのタスクが残ってしまうようです
GC.Collect()を実行すると End Sub を実行後 タスクが消えました^^
Excel.Application型の変数はローカル変数で検証ですが ・・・
当方の環境 VB2005 + Excel2003
これはなんとredfox63 様.
先日も2度ほどアドバイスいただいております,わたくしcamputerと申します.
閲覧してくださりましてどうもありがとうございます.
アドバイスいただいたとおりGC.Collect()を早速入れてみたところ,見事に消えました.
非常ーーーーーーーーに嬉しいです.どうもありがとうございます.
お手元の環境で試験してくださったようで,本当にどうもありがとうございます.
念のため,今後同じ問題を抱えて閲覧される方のために書いておきますと,
私の環境
Vista,VB2008,Excel2007
でもこのやり方で解放されました.
しかしこれでようやく解放かと大喜びまして次のようにaxesまで
3つのオブジェクトを追加したらまた解放不可に........
Dim ChartObject As Object
Dim ChartObjects = xlSheet.ChartObjects
For Each ChartObject In ChartObjects
ChartObject.Activate()
Dim myChart As Object = ChartObject.Chart
Dim myChartTitle As Object = myChart.ChartTitle
Dim myAxes As Object = myChart.Axes()
MRComObject(myChartTitle) : myChartTitle = Nothing
MRComObject(myChart) : myChart = Nothing
MRComObject(myAxes) : myAxes = Nothing
MRComObject(ChartObject) : ChartObject = Nothing
Next
MRComObject(ChartObjects) : ChartObjects = Nothing
GC.Collect()で検索してひっかかるよく似たコード(GC.WaitForPendingFinalizers()とか)を
何個かプロシージャ最後に追加してみましたがうまくいきません...
これについては別質問になりそうですので,今晩自分で考えます.
この解決方法は自分では見つけられなかったと思います.
閲覧していただけてよかったです.
本当にどうもありがとうございました.
camputer
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBAが止まります。 2 2022/09/02 14:02
- Visual Basic(VBA) Excel vbaについての質問 3 2023/04/18 16:14
- Visual Basic(VBA) エクセルのマクロを使ってメールを送る方法について教えてください 2 2022/03/29 01:36
- Visual Basic(VBA) 複数のcsvファイルをExcelに一括変換したい 2 2023/03/03 12:44
- Visual Basic(VBA) 【VBAエラー】Nextに対するForがありません 対策について 5 2022/11/21 21:26
- Visual Basic(VBA) エクセルVBAのコードで質問です。 下のコードはJ16の文字列をB3を起点とする範囲から探して、見つ 5 2023/04/07 11:07
- Visual Basic(VBA) VBA This Workbookモジュールを別ファイルにコピーする方法 1 2022/09/14 01:51
- Visual Basic(VBA) ユーザーフォームに2つのコンボボックス銀行名「ConboBox1」支店名を「ConboBox2」とし 4 2022/08/03 17:34
- Visual Basic(VBA) このVBAでExcelアプリケーションを作成は必要ですか? 3 2023/07/19 21:13
- Visual Basic(VBA) 形式を選択して貼り付け 以下のコードで「元」シートと「先」シートのA列に同じ値があったら指定範囲をコ 5 2022/11/11 07:30
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
タスクスケジューラでbatがスケ...
-
oppo reno 7A
-
フォルダーに緑のレ点と赤の✖が...
-
gcc13.2のバグ?
-
検索ボタンなどに使う虫眼鏡の...
-
WindowsUpdateでウイルスセキュ...
-
Linuxでの開発環境構築や設定の...
-
フリーソフトをうまくダウンロ...
-
オブジェクト指向開発とコンポ...
-
AccessからExcelのVBAを動かしたい
-
レイノルズ数が4000より大きい...
-
pixiaをインストールできないん...
-
ユーザー毎にProgram Files
-
VScodeでデバッグするときの文...
-
VB.net webアプリケーション 戻...
-
最近のXcodeに必要なスペック
-
[python]スクリプトから起動で...
-
コマンドプロンプト start コマ...
-
管理者権限でないと実行できな...
-
オートマトン: npdaとdpdaの違い
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VB2005 BackgroundWorkerの使用
-
タスクスケジューラでbatがスケ...
-
決められた時間間隔で処理を繰...
-
バッチファイルのタスクスケジ...
-
oppo reno 7A
-
フォルダーに緑のレ点と赤の✖が...
-
日本に、Microsoftのような会社...
-
インストールが不要なソフトは...
-
Linuxでの開発環境構築や設定の...
-
gcc13.2のバグ?
-
特定ユーザに対してのみアプリ...
-
windows10のアプリと機能にyout...
-
回復ドライブに保存されるもの
-
WindowsDefender以外のウイルス...
-
Beckyのアドレス帳を上下に移動...
-
Android studio 初心者 Hello A...
-
ペイント(mspaint.exe)がない...
-
vbsでデバッグしながらコードを...
-
Inkscape プリントマークでエラー
-
VC++にてボタン等のサイズ取得
おすすめ情報