トップ回答者
DataGridへバインド時にハンドルされてないエラーが発生します。

質問
-
初めて投稿させていただきます。
いろいろ探したのですが自分ではそれらしい事象を発見することができず、
投稿させていただきます。
*環境
VB.NET2003、
SQLServer2005
.NET Framework 1.1
内容は、DataGridで行にカーソルを置いたい状態で再度データをバインドした場合に以下エラーが発生してしまいます。
<エラーメッセージ>
'System.Argument.Exception'のハンドルされていない例外が system.data.dllで発生しました。
追加情報:列'xxx'はテーブル Tableに属していません。
プログラムをDebugモードで動かした場合にはメッセージで止まりますが、
普通に動かした場合にはメッセージが出力され、DataGrid全体に赤い×印のようなものが表示されます。
画面の構成としては
抽出条件選択のTextBoxと、表示処理ボタン、結果表示用のDataGridがあります。
まず、画面指定の抽出条件に従ってDBから抽出した内容をDatasetに対してセットし、
DataGridにバインドします。
これでDataGridに内容が表示されます。
次に
抽出条件は変更せず、DataGridに表示されているセルのどこか1セルを選択し、同じ内容・同じ条件でもう一度
DataGridにデータを表示させようとします。
そうするとなぜかバインドする時に前述のエラーが発生します。
プログラム上グリッド上でマウスがあるなしのイベント等もハンドルしていません。
また、違うロジックを通っているわけでもありません。
それにも関わらず、グリッド上にマウスカーソルを置いただけで何かしらバインド時に影響が出るのでしょうか?
心当たりのあるお方がいればご助言をいただきたくお願いいたします。
まったく見当違いの質問をしていたりするようでしたら本当に申し訳ないですが
よろしくお願いします。
*追記*
エラーが発生時のメッセージにある追加情報より、Dataset内の"Table"をウォッチしてみましたが、
該当のColumnは存在していました。
回答
-
もんち さんからの引用
検索を行う場合、サンプルの「TESTA」というプロシージャを頭から通る事になります。定義上で「Dim dsGrid as New Dataset」の定義から"dsGrid"内のテーブル"Table"は削除されると思っています。
すみません。見逃していました。ただ、このことが気になりました。DataGridにバインドされた状態でDataSetが消えてしまっているようなことはないでしょうか? もしそうであれば、それが影響しているのかもしれません。もんち さんからの引用
抽出条件に従ってDBから取得した情報をさらに編集(数値フォーマットや日付、値の演算や判断結果の出力等)するため、DBから取得した情報をもとに編集した値をグリッド表示用Datatableに格納するような形になっています。
了解しました。ただ、フォーマットはDataGrid自身で可能ですし、値の演算や判断結果も、SQL文やストアドプロシージャで処理可能なことがほとんどです。そうしておけばそのままDataGridへバインドするだけで済みます。次に開発される時には候補に挙げてみて下さい。
(既にご存知であれば蛇足なので無視して下さい。) -
trapemiyaさん、どうもありがとうございます。
まだ完全かどうかわかりませんが、
ご返信いただいた内容をヒントにエラーが発生する状況は回避できるようになりました。
>すみません。見逃していました。ただ、このことが気になりました。DataGridにバインドされた状態でDataSetが消えてしまっ
>ているようなことはないでしょうか? もしそうであれば、それが影響しているのかもしれません。
上記より、1回目表示時、DataGridにバインドされていた内容(DataSource)がDataGrid上にそのまま残っていることに
気がつきました。
そこで試しにバインドする直前に以下コードを入れてみて動かしてみました。
DataGrid.DataSource = Nothing
するとカーソルを置いていようがどうしようがエラーが発生することはなくなりました。
ただ、どうしてカーソルを置いたときだけ発生したのか等の理由がいまだに不明なので
これで正しいのかどうかもわからないのですが、とりあえず様子を見ようかと思います。
何度もアドバイスをいただき本当にありがとうございました。
>了解しました。ただ、フォーマットはDataGrid自身で可能ですし、値の演算や判断結果も、SQL文やストアドプロシージャで
>処理可能なことがほとんどです。そうしておけばそのままDataGridへバインドするだけで済みます。次に開発される時には
>候補に挙げてみて下さい。
まだまだ勉強不足であることを感じました。いろいろもっと勉強させていただきます。
どうもありがとうございました。
すべての返信
-
trapemiyaさん、さっそく返信いただきありがとうございます。
Debugモードで追いかけた場合にエラーになるのはまさにDataSetをバインドするときです。
おおまかに編集した形で申し訳ないんですが、プログラムサンプルです。
Private Sub TESTA()
Dim dsTemp as New Dataset,dsGrid as New Dataset
Dim tbTemp as DataTable
Dim rwTemp as DataRow
tbTemp = New DataTable("Table")
dsGrid.Tables.Add("Table")tbTemp.Columns.Add(New DataClumn("xxx"),GetType(String)))
tbTemp.Columns.Add(New DataClumn("yyy"),GetType(String)))
tbTemp.Columns.Add(New DataClumn("zzz"),GetType(String)))
~ こういった具合で20列分追加~
DBから情報を取得し、取得したデータ数分For LoopでDatasetにAdd
Loop内処理
rwTemp = tbTemp.NewRow()
rwTemp(0) = dsTemp.Tables(0).Rows(i).Item(0)
rwTemp(1) = dsTemp.Tables(0).Rows(i).Item(1)~ 20ColumnそれぞれにDBからの情報をセット~
dsGrid.Tables(0).Rows.Add(rwTemp)Loop終了
dgDataGrid.SetDataBinding(dsGrid,"Table") ←ここで例外エラー発生
END SUB
やはりカーソルを置いただけではバインドに影響は出ないですよね。。。
いろいろ情報がないかDebugで追いかけてみます。
-
ちなみにDataGridにカーソルを置かない場合はエラーにならないのでしょうか?
また、提示されたコードを見る限り複雑なことをされていますので、その辺りに問題が潜んでいそうな気がします。
二回目の検索時にはTableというデータテーブルを削除してから処理をする必要があると思うのですが、その辺りのロジックは大丈夫でしょうか?
また、Tableという名前はデータテーブルの名前が省略された時のデフォルトで付けられる名前ですので、その名前を明示的に付けることには少し違和感があります。#本題とは離れますが、DataGridに値を表示するだけでしたら、データベースから作成したデータテーブルをDataGridにバインドするだけですが、このようなロジックにされているのは、何か理由があるのでしょうか?
-
trapemiyaさん、たびたご回答いただきありがとうございます。
>ちなみにDataGridにカーソルを置かない場合はエラーにならないのでしょうか?
ならないのです。。。
1回目検索結果が表示されたグリッド上にカーソルを置いたまま2回目の検索を行うとエラーになります。
1回目検索結果表示後2回目をそのまま検索したり、もしくはグリッド以外の部分にカーソルを当てたり、
抽出条件入力用テキストボックスにカーソルを置いて2回目の検索を行っても正常に表示されます。
>二回目の検索時にはTableというデータテーブルを削除してから処理をする必要があると思うのですが、その辺りのロジックは
>大丈夫でしょうか?
検索を行う場合、サンプルの「TESTA」というプロシージャを頭から通る事になります。
定義上で「Dim dsGrid as New Dataset」の定義から"dsGrid"内のテーブル"Table"は削除されると思っています。
(間違ってたらなんなのですが・・・)
>また、Tableという名前はデータテーブルの名前が省略された時のデフォルトで付けられる名前ですので、その名前を明示的に
>付けることには少し違和感があります。
デフォルト名が"Table"というのは初めて知りました。
ただ、プログラムコード上各プロシ-ジャから呼び出されるため、今からの変更はきついです。。
>#本題とは離れますが、DataGridに値を表示するだけでしたら、データベースから作成したデータテーブルをDataGridに
>バインドするだけですが、このようなロジックにされているのは、何か理由があるのでしょうか?
サンプル上かなり削っているので申し訳ないのですが、
抽出条件に従ってDBから取得した情報をさらに編集(数値フォーマットや日付、値の演算や判断結果の出力等)するため、
DBから取得した情報をもとに編集した値をグリッド表示用Datatableに格納するような形になっています。
なおその後の確認の結果、
・カーソルを置いた列がTableに属していないエラーになる
・グリッド上右のほう(10列目以上?)の列にカーソルを置いた場合は100%発生
・グリッド上左のほうの列にカーソルを置いた場合、発生しずらい
のような形です。
何かありましたらまた追記させていただきます。
-
もんち さんからの引用
検索を行う場合、サンプルの「TESTA」というプロシージャを頭から通る事になります。定義上で「Dim dsGrid as New Dataset」の定義から"dsGrid"内のテーブル"Table"は削除されると思っています。
すみません。見逃していました。ただ、このことが気になりました。DataGridにバインドされた状態でDataSetが消えてしまっているようなことはないでしょうか? もしそうであれば、それが影響しているのかもしれません。もんち さんからの引用
抽出条件に従ってDBから取得した情報をさらに編集(数値フォーマットや日付、値の演算や判断結果の出力等)するため、DBから取得した情報をもとに編集した値をグリッド表示用Datatableに格納するような形になっています。
了解しました。ただ、フォーマットはDataGrid自身で可能ですし、値の演算や判断結果も、SQL文やストアドプロシージャで処理可能なことがほとんどです。そうしておけばそのままDataGridへバインドするだけで済みます。次に開発される時には候補に挙げてみて下さい。
(既にご存知であれば蛇足なので無視して下さい。) -
trapemiyaさん、どうもありがとうございます。
まだ完全かどうかわかりませんが、
ご返信いただいた内容をヒントにエラーが発生する状況は回避できるようになりました。
>すみません。見逃していました。ただ、このことが気になりました。DataGridにバインドされた状態でDataSetが消えてしまっ
>ているようなことはないでしょうか? もしそうであれば、それが影響しているのかもしれません。
上記より、1回目表示時、DataGridにバインドされていた内容(DataSource)がDataGrid上にそのまま残っていることに
気がつきました。
そこで試しにバインドする直前に以下コードを入れてみて動かしてみました。
DataGrid.DataSource = Nothing
するとカーソルを置いていようがどうしようがエラーが発生することはなくなりました。
ただ、どうしてカーソルを置いたときだけ発生したのか等の理由がいまだに不明なので
これで正しいのかどうかもわからないのですが、とりあえず様子を見ようかと思います。
何度もアドバイスをいただき本当にありがとうございました。
>了解しました。ただ、フォーマットはDataGrid自身で可能ですし、値の演算や判断結果も、SQL文やストアドプロシージャで
>処理可能なことがほとんどです。そうしておけばそのままDataGridへバインドするだけで済みます。次に開発される時には
>候補に挙げてみて下さい。
まだまだ勉強不足であることを感じました。いろいろもっと勉強させていただきます。
どうもありがとうございました。
-
もんち さんからの引用 ただ、どうしてカーソルを置いたときだけ発生したのか等の理由がいまだに不明なので
これで正しいのかどうかもわからないのですが、とりあえず様子を見ようかと思います。
たぶん、DataGridにフォーカスがあたっているため、DataGridが何かしようとしてこけるのでしょう。この辺りはブラックボックスなのでよくわかりません。
しかし、DataGridのDataSourceからDataSetを一旦外し、DataSetをきちんと作り直してからふたたびDataGridのDataSourceにDataSetを割り当てることは、ロジック的に誤りではないので、たぶんこれで問題ないと思います。