C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

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

Excelがフリーズする


(過去ログ 8 を表示中)

[トピック内 12 記事 (1 - 12 表示)]  << 0 >>

■9214 / inTopicNo.1)  Excelがフリーズする
  
□投稿者/ 廿六木(かなり初心者 二等兵(10回)-(2006/12/15(Fri) 16:29:48)

分類:[VB.NET] 


分類:[VB.NET] 

お世話になります。以前の投稿でCOMオブジェクトはすべて解放したはずなのですが、
↓のプログラム(Excel操作部分のみ)を実行して
Excelファイルを再度開こうとするとフリーズしてしまいます。

*********************************************************************************************
Dim xlApp As Excel.Application

Try
xlApp = New Excel.Application

Dim xlBooks As Excel.Workbooks = xlApp.Workbooks

Try
Dim xlFilePath As String = "C:\Excel.xls"

Dim xlBook As Excel.Workbook = xlBooks.Open(xlFilePath)
Try
Dim xlSheets As Excel.Sheets = xlBook.Worksheets
Try
Dim xlSheet As Excel.Worksheet = xlSheets.Item(6)

Try
xlApp.Visible = True

'=========== オートフィルタを一時解除 =============
If xlSheet.FilterMode = True Then
xlSheet.AutoFilterMode = False
End If

Dim xlRange As Excel.Range
Dim strDat(18000, 31) As Object
Dim myRow As DataRow
Dim myColumn As DataColumn
Dim rowIndex As Integer '配列の行番号
Dim colIndex As Integer '配列の列番号

Try
xlRange = xlSheet.Range("A1:AE15000")
'=============== データの作成 ====================
rowIndex = 0
colIndex = 0
For Each myRow In dv.Table.Rows
For Each myColumn In dv.Table.Columns
strDat(rowIndex, colIndex) = myRow(myColumn)
colIndex += 1 '列インクリメント
Next
colIndex = 0 '行番号を初期化
rowIndex += 1 '行インクリメント
Next

'=============== Excelに二次元配列(strDat)を放り込む ======
xlRange.Value = strDat
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange)

'============ オートフィルタの設定 ==================
If xlSheet.FilterMode = False Then
xlRange = xlSheet.Range("A1")
xlRange.AutoFilter(1)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange)
End If

'============== ファイルの保存処理 ===============
xlApp.DisplayAlerts = False
xlSheet.SaveAs(xlFilePath)
xlApp.DisplayAlerts = True

Finally
If Not xlRange Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange)
End If
End Try

Finally
If Not xlSheet Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet)
End If
End Try
Finally
If Not xlSheets Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets)
End If
End Try
Finally
If Not xlBook Is Nothing Then
Try
xlBook.Close()
Finally
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
End Try
End If
End Try

Finally
If Not xlBooks Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
End If
End Try
Finally
If Not xlApp Is Nothing Then
Try
xlApp.Quit()
Finally
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
End Try
End If
End Try
****************************************************************************************************
↑のプログラム(必要な部分だけ)におきまして、部分的にコメントにして問題箇所を
調べたところ、二次元配列を作る部分に問題があることがわかりました。
でもこの部分にはCOMオブジェクトらしきものはないと思うので、何を解放してやればよいのか
わかりません。よろしくお願いします。
'=============== データの作成 ====================
rowIndex = 0
colIndex = 0
For Each myRow In dv.Table.Rows
For Each myColumn In dv.Table.Columns
strDat(rowIndex, colIndex) = myRow(myColumn)
colIndex += 1 '列インクリメント
Next
colIndex = 0 '行番号を初期化
rowIndex += 1 '行インクリメント
Next

0
引用返信 編集キー/
■9216 / inTopicNo.2)  Re[1]: Excelがフリーズする
□投稿者/ 渋木宏明(ひどり) 伍長(56回)-(2006/12/15(Fri) 17:00:28)
渋木宏明(ひどり) さんの Web サイト

分類:[VB.NET] 

> お世話になります。以前の投稿でCOMオブジェクトはすべて解放したはずなのですが、

ダウト。For Each 使ってるじゃないですか。
For Each で回すと暗黙の参照が発生して解放漏れが起きますよ。


0
引用返信 編集キー/
■9222 / inTopicNo.3)  Re[2]: Excelがフリーズする
□投稿者/ あきひろ 一等兵(22回)-(2006/12/15(Fri) 18:49:40)

分類:[VB.NET] 

> お世話になります。以前の投稿でCOMオブジェクトはすべて解放したはずなのですが、

渋木さんの言われるとおり、For Eachがまずいと思われます。

アプリが終了した後に、タスクマネージャーを立ち上げて、「Excel.exe」が残っていないかを確認するようにしたほうが良いです(当方Excel2000使いなので、最近のExcelの挙動が違ってたらごめんなさい)。

「はず」とか「つもり」ではなく、実際に確認する習慣をつけたほうが良いです。
ある程度経験を積んだ人間は、「はず」とか「つもり」がいかにあてにならないかを身をもってしっていますので。そしてそれを多用する人間は、どんどんと信用を失っていきます。。。


0
引用返信 編集キー/
■9223 / inTopicNo.4)  Re[3]: Excelがフリーズする
□投稿者/ ま 二等兵(1回)-(2006/12/15(Fri) 19:10:49)

分類:[VB.NET] 

 そのコードで うまくいきましたよ
データベースは 適当なのを設定しましたが・・・

もっと別の部位じゃないですか

0
引用返信 編集キー/
■9237 / inTopicNo.5)  Re[2]: Excelがフリーズする
□投稿者/ 特攻隊長まるるう 伍長(42回)-(2006/12/16(Sat) 14:48:49)

分類:[VB.NET] 

No9216に返信(渋木宏明(ひどり)さんの記事)
前スレ http://f57.aaa.livedoor.jp/~jeanne/bbs/faq.cgi?mode=al2&namber=8961
前々スレ http://f57.aaa.livedoor.jp/~jeanne/bbs/faq.cgi?mode=al2&namber=8611

> ダウト。For Each 使ってるじゃないですか。
んん。。。流し読みなので間違ってたらごめんなさい。

問題とされてる個所は dv (DataView?)のデータテーブルの
処理だから ADO.NET の処理で、だから
> でもこの部分にはCOMオブジェクトらしきものはないと思うので
ってなってるようです。。。

とりあえず dv のデータを Excel から取ってる…とかはないよね。。。?
どこからどうやって取ってるの?

> 「はず」とか「つもり」ではなく、実際に確認する習慣をつけたほうが良いです。
には賛成で、再確認するけど、

・プログラム実行前にタスクマネージャで EXCEL.EXE のプロセスが1個も
無いことを確認している?
・問題の個所のループ処理をコメントアウトしたら、タスクマネージャで
EXCEL.EXE のプロセスは残らない?
・他は同じ条件で、問題の個所のループ処理を実行したら、タスクマネージャで
EXCEL.EXE のプロセスが残る?
・しばらく時間を置いても EXCEL.EXE のプロセスは残ったまま?

…というような、回答者が判断できるような事実までしっかり伝えてください。
# 自分で確認・判断することは重要だけど、その確認方法が間違ってる
# 場合もあるから。
ちなみに同じ条件で3回は実行して、再現性を確認してください。

結構、大量のデータを扱ってるなら、保存処理だけに数秒掛かる事もあるから、
少しデータ量を少なくしてテストしてみるとか。。。
全く違う側面から考えて。。。リビルドしてみるとか。。。新規プロジェクトに
問題の部分のコードのみ移植して実行してみるとか。。。
単純にコードをコメントアウトするだけでなく、条件を変えて何か変化しない
か?調べてください。

> Excelがフリーズする
ちなみにフリーズしてるわけではなくて、表示処理が上手く行われない
だけでしょう。エクセルの仕様として、既に Excel が起動されている場合に
そのプロセスを利用しようとするので、中途半端に破棄されたプロセスで
ファイルを開こうとして表示できないみたい。
(注:適当な解釈です。ちゃんと調べたわけじゃありません。正確な情報
が必要な場合は、自分で調べてください)
だから、表示がおかしいウィンドウを手作業で閉じると、次からは正常起動
できる場合もあります。

0
引用返信 編集キー/
■9246 / inTopicNo.6)  Re[3]: Excelがフリーズする
□投稿者/ 渋木宏明(ひどり) 伍長(58回)-(2006/12/16(Sat) 23:02:21)
渋木宏明(ひどり) さんの Web サイト

分類:[VB.NET] 

> 問題とされてる個所は dv (DataView?)のデータテーブルの
> 処理だから ADO.NET の処理で、だから
>>でもこの部分にはCOMオブジェクトらしきものはないと思うので
> ってなってるようです。。。

ごめんなさい、dv は Excel 系のオブジェクトじゃないんですか。

とすると、他には怪しげなところは見当たらないような。。。


0
引用返信 編集キー/
■9279 / inTopicNo.7)  Re[4]: Excelがフリーズする
□投稿者/ 廿六木(かなり初心者 二等兵(11回)-(2006/12/18(Mon) 08:29:37)

分類:[VB.NET] 

ありがとうございます。
元のデータはCSV形式のファイルでそれをDataTableに格納して、それを既存のExcelに出力しています。
抜けていましたが、プログラム作成しているパソコンのXPでは問題ないのですが、会社の他のWindows98で実行したところ、このような現象が起こります。
状況を詳しく説明しますと、プログラム実行前にはExcelは開いてないです。
そして問題の箇所をコメントアウトして実行したら、Excel.exeは残らないです。
問題箇所も入れて実行したら、プログラム上の「オートフィルタの設定」という箇所と、「ファイルの保存処理」という箇所が実行されておらず、またExcelは閉じるはずなのに、閉じない状態です。
以上がプログラムを実行した時の状況です。
それからExcelを手動で閉じてから、タスクマネージャで確認してもExcel.exeとVB.netの実行ファイルも残ったままです。
その状態で、再度そのExcelファイルを開こうとしても開けません。
以上が現状試した結果です。


0
引用返信 編集キー/
■9280 / inTopicNo.8)  Re[5]: Excelがフリーズする
□投稿者/ あきひろ 一等兵(23回)-(2006/12/18(Mon) 09:14:17)

分類:[VB.NET] 

おぉぉ、本当だFor Eachじゃないや。自らの不明を恥じるばかりです。とほほ。

症状から察するに、どこぞで例外が出ているのに、COMの開放がうまいこと
いってないっぽいですね。コードを見る限りは問題無さそうにも見えますが、
私の大丈夫はあてになりませんしねートホホ。

 とりあえず、問題が発生する場合の正確な処理のパスを掴むようにするのが
よろしいかと。自分がよくやるのは、全てのブロックの入り口で、通し番号を
ログに出力します。これで、どこでエラーが発生したのかと、エラーが発生した後に
どの順で例外処理が実施されたかが把握できるはずです。
 それと廿六木さんの調査で、問題箇所のあたりはついているようですが、正確な
位置を特定すると、問題解決のヒントになるかもしれません。

 大抵この手の問題は、例外処理してる最中にまた例外ってのがよくある
パターンなのですが、それも見る限り大丈夫っぽいしなぁ。。。

 あと一応Excelのバージョンも提示すると、エライ人がひらめいてくれるかも
しれません。



0
引用返信 編集キー/
■9281 / inTopicNo.9)  Re[6]: Excelがフリーズする
□投稿者/ 廿六木(かなり初心者 二等兵(12回)-(2006/12/18(Mon) 10:28:52)

分類:[VB.NET] 

Excel2000です。

0
引用返信 編集キー/
■9283 / inTopicNo.10)  Re[5]: Excelがフリーズする
□投稿者/ 魔界の仮面弁士 中佐(212回)-(2006/12/18(Mon) 10:54:58)

分類:[VB.NET] 

No9279に返信(廿六木(かなり初心者さんの記事)
> 会社の他のWindows98で実行したところ、このような現象が起こります。

9x 系からの Excel 操作がありえるのならば、
1.8万行を一括転送するのは避けた方が良いかと思います。

さしあたり、
・巨大なデータを送るときは、複数回に分割して送信する。
・OpenText や OpenXML で開くことも要検討。
・かつ、Excel の操作回数はできるだけ減らすこと。
いったという点に気をつけてみてください。
http://support.microsoft.com/kb/414107/ja

それでも駄目なら、効果は薄いかも知れませんが、配列サイズの変換を避けるため、
Range.Value に渡す配列のインデックスを、Excel にあわせた 1 ベースの物に
修正してみるとか。たとえば、下記のようなコードを実行すると、最後の配列は、
VB.NET で作成可能な V(0, 0)〜V(5, 2) という 0 ベースの範囲のものではなく、
V(1, 1)〜V(6, 3) という 1 ベースの範囲の値として取得されます。

Option Strict Off
Module Module1
Sub Main()
Dim X As Object = CreateObject("Excel.Application")
X.Visible = True
Dim Bs As Object = X.Workbooks
Dim B As Object = Bs.Add()
Dim Ss As Object = B.Sheets
Dim S As Object = Ss(1)
Dim R As Object = S.Range("A5:C10")
Dim V(,) As Object = R.Value
'解放コードは省略
End Sub
End Module


0
引用返信 編集キー/
■9288 / inTopicNo.11)  Re[7]: Excelがフリーズする
□投稿者/ 特攻隊長まるるう 伍長(44回)-(2006/12/18(Mon) 11:45:46)

分類:[VB.NET] 

No9281に返信(廿六木(かなり初心者さんの記事)
# 魔界の仮面弁士さんが書込まれているので、ちょっと少し違った視点を意識して書いてみます。

> 問題箇所も入れて実行したら、プログラム上の「オートフィルタの設定」という箇所と、
> 「ファイルの保存処理」という箇所が実行されておらず、またExcelは閉じるはずなのに、
> 閉じない状態です。
あきひろさんも言われてますが、エラーが起こって例外処理になっているようです。
  xlRange.Value = strDat
でエラーが起こってますかねぇ。。。(?)

> それからExcelを手動で閉じてから、タスクマネージャで確認してもExcel.exeと
> VB.netの実行ファイルも残ったままです。
本来は例外処理が起こっても解放できるように考えられたコードなのですが、
…解放できませんか。。。んー。

> プログラム作成しているパソコンのXPでは問題ないのですが、会社の他のWindows98で実行したところ
> Excel2000です。
Excel のバージョンが違うのは色々と問題が起こり易い。。。

あと、Windows98 って Microsoft .NET Framework の動作保証ありましたっけ?
互換性を考える場合、より下位の環境で開発するのが常識です。
個人的には、[VB.NET]での開発はやめて、[Excel2000 VBA]のマクロによる
プログラムにした方が良いと思います。

[VB.NET]で開発するとして、
最終的に参照設定を外して実行時バインディングにする必要があるかも。。。
# ↑魔界の仮面弁士さんのサンプルコードを参考に。。。
テストの内容を聞くと、エラーの起こるPCでデバッグしていますよね?
その時点でバージョン違いのコンパイルエラーは出たりしなかったですか?

とりあえず、Finally の前に
[VB.NET]
 Catch ex As Exception
  Debug.WriteLine(ex.Message)
等を入れてエラーメッセージを確認してみてください。

セルへの代入でエラーが起こる場合で一番多いのは、代入する値にエラーが
ある場合です。計算式(セル参照式)とか入れていませんか?Excel2000 では
受け付けてくれないデータが無いか?確認してください。

0
引用返信 編集キー/
■9296 / inTopicNo.12)  Re[8]: Excelがフリーズする
□投稿者/ 魔界の仮面弁士 中佐(213回)-(2006/12/18(Mon) 13:32:28)

分類:[VB.NET] 

No9288に返信(特攻隊長まるるうさんの記事)
> あと、Windows98 って Microsoft .NET Framework の動作保証ありましたっけ?
サポートしていないのは、.NET Framework 3.0 の場合ですね。
.NET Framework 1.x および 2.0 環境は、Win98 上で動作を保証しています。

> 最終的に参照設定を外して実行時バインディングにする必要があるかも。。。
.NET から Excel を実行時バインドすると、参照カウントが内部的な型変換に
よって増加してしまい、また別の問題を引き起こす可能性があります。
Excel のバージョンが固定的な場合には、事前バインドを採用することを
個人的にはお奨めします。

# これが VB6 や VBA の場合であれば、実行時バインドを採用しておくと、
# Global Instancing Objectの参照によるオブジェクトの解放漏れを
# 排除できるので、COM の解放という面では安全なんですけれどもね…。(^^;

> 等を入れてエラーメッセージを確認してみてください。
エラーが発生しているのではなく、処理がハングアップしているか…もしくは
処理にものすごく長い時間が掛かっている、という状況かも知れませんね。

0
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -