タイトル : Re^2: ループ処理後にExcelのタスクが残る 投稿日 : 2020/03/02(Mon) 19:15 投稿者 : mogi
魔界の仮面弁士さん アドバイスありがとうございます。 返信が遅くなり申し訳ありません。 > > Dim xlwkSheet2 As Worksheet = Nothing > > Dim xlCells As Range = Nothing > > Dim xlRange As Range = Nothing > > 'シートのコピー > > xlwkSheet2.Copy(After:=xlSheet(i+1)) > 上記は明らかに不自然です。 > Nothing なオブジェクトに対して Copy メソッドを呼び出そうとすれば、 > NullReferenceException の例外になってしまうはずですよね。 > > もしかして「xlwkSheet.Copy(After:=xlSheet(i+1))」の間違い? すみません、これは記述ミスでご推察の通り「xlwkSheet.Copy(After:=xlSheet(i+1))」の間違いです。 > > xlwkSheet2.Name = "A" + i > 上記は「コンパイルエラー」になってしまい、実行すらできないはず…。 > どのバージョンの VB をお使いでしょうか? こちらも記述ミスです。実際は違う値が入力され、実行できるものになっています。 省略できる部分を省略しようと思ったのですが、当方の知識不足で混乱させてしまい申し訳ありません。 > 提示頂いたコードが不完全なので確証は持てませんが、根本的には > Sheet 型のインスタンスを保持・解放し忘れているのが原因だと思います。 > > 特に、xlSheet(i+1) の戻り値は、As Object であることも要因の一つです。 > また、「COM オブジェクトを引数に取るメソッド」に対して、 > 明示的な型ではなく、汎用の Object 型を通じて引数を渡した場合、 > 内部的な型判定の際に参照カウントが増加しやすくなるという傾向があります。 原因はご指摘の通り、xlSheet(i+1)の戻り値がAs Objectであるためでした。 (参考したサイトにも同じことが書かれていたのにも関わらず恥ずかしい限りです。) >引数に渡す COM オブジェクトも変数に受け、解放するようにしてください。 >正しい Copy 手順については、次の投稿にて後述します。 書いていただいたコードを参考にし、xlSheet(i+1)をWorkSheet型にキャストし代入の後、 Copyメソッドを実行することでExcelのプロセスが残ることなく終了するようになりました。 原因はxlSheet(i+1)がObject型になることを知らなったことです。 また、確かにご指摘の通り可読性の面から変数名も良くないと感じたため訂正致します。 > 引数として COM オブジェクトを引き渡す必要がある場合は、 > 「そのインスタンスを変数に保持しておく」 > 「Object 型ではなく、正しい型で渡すようにする」 > 「引数に渡し終わった後は、きちんと解放する」の 3 つを守りましょう。 漸くこの辺が理解できて来たと思った矢先にこのバグでした。 改めて意識するように努めます。 最後になりますが、今回はこちら側が提示したコードが不完全なものにも関わらず 問題を見つけて下さった上に、サンプルコードまで書いて頂き本当にありがとうございました。 大変助かりました。また、掲題の件以外にも細かなアドバイスを下さり参考になりました。 今後も初歩的な部分でお世話になるかもしれませんが、その際はどうかよろしくお願いします。 |