- PR -

TextBoxとフィールドを連結してデータ更新

1
投稿者投稿内容
バニラミント
ベテラン
会議室デビュー日: 2005/05/27
投稿数: 58
投稿日時: 2007-06-26 11:50
C#でWindowsアプリを開発しています。
そのアプリの中でマスタファイルの保守部分を作成中に
どうしてもクリアできない部分2点ほどあります。
ここが間違っているなどのご指摘、アドバイスをいただければ幸いです。
よろしくお願いします。


マスタテーブルは次のような定義です
-------------------------------------
テーブル(商品)
商品コード int 4 (主キー)
名称 varchar 60
略称 varchar 30
以下略(残りフィールド数は17ほどあります)
-------------------------------------


DataSetを作成して、DataBindingsでTextBoxとフィールドを連結し、
Windowsフォーム上でTextBoxの値を更新しテスト用に作成したButtonを
クリックしてこのような感じでMessageboxを表示させました。
>MessageBox.Show(dtset.Tables["t_商品"].Rows[0]["名称"].ToString());
>MessageBox.Show(dtset.Tables["t_商品"].Rows[0]["略称"].ToString());

データの修正の場合は、名称、略称など主キー以外を修正するだけなのですが、
マスタ保守の仕様として複写登録があり、複写対象のデータを表示して
新しく主キー(商品コード)を作成する必要があります。

新規の商品コードの発行は、商品コード発行ボタンをクリックしたら
「SELECT 商品コード FROM 商品 ORDER BY 商品コード DESC」
で、商品コードを取得し、その値に+1した値を表示させるようにしました。

画面上では、商品コードは変わっているのですが、
>MessageBox.Show(dtset.Tables["t_商品"].Rows[0]["商品コード"].ToString());
として確認してみると、前のコードのままです。

「名称」や「略称」と同じような処理をしているのですがコードだけが
変化なくどのようにすればよいか悩んでいます。
TextBoxと連結しない方法で処理を考えたほうがよいでしょうか?


あともう1点は、
修正や複写に関しては、DataSetを作成し連結して・・・と
処理は作れそうなのですが、新規の場合は連結するためのDataSetをどのように
作ればよいのか・・・と考えています。

いろいろ調べてみたところ、DataSetにテーブルを作成し、Columns.Addで
フィールドを追加するという方法を見つけました。

この方法を使えば、空のDataSetを作成し、その中にデータを書き込めば
大丈夫かなと思うのですが。。。
マスタが大量にあった場合など、メンテナンスのことを考えると
非常に効率が悪そうに思えます。
他に良い方法がありますでしょうか?


------------- DataSet作成部分とデータ連結部分のソースです
//DataSet作成部分
DataSet dtset = new DataSet("t_商品");
string sqltxt = "SELECT * FROM 商品 WHERE 商品コード=" + TextBox1.Text;
OdbcDataAdapter dadp = new OdbcDataAdapter(sqltxt, cn);
dadp.Fill(dtset,"t_商品");

//TextBoxとDataSetを連結している部分
TextBox1.DataBindings.Add("Text",dtset.Tables["t_商品"],"商品コード");
TextBox2.DataBindings.Add("Text",dtset.Tables["t_商品"],"名称");
TextBox3.DataBindings.Add("Text",dtset.Tables["t_商品"],"略称");
TextBox・・・以下略
------------------------------------------------------------------------
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-06-26 21:00
複写:
新しい行を作るように実装します。キー以外はコピー。
キーの発行は、単純な数値なら、シーケンスを作るのが上策。

もう一つのほうは、意味がわかりませんでした。
テーブルを追加する?


[ メッセージ編集済み 編集者: Jitta 編集日時 2007-06-26 21:01 ]
バニラミント
ベテラン
会議室デビュー日: 2005/05/27
投稿数: 58
投稿日時: 2007-06-27 16:01
Jittaさん、レスありがとうございます。

>>新しい行を作るように実装します。キー以外はコピー。
コピーということはDataSetのCloneメソッドを使うということでしょうか?

>>もう一つのほうは、意味がわかりませんでした。
説明不足ですみません。
複写や更新の場合は元になるDataSetを作成できるのですが
新規の場合は、テーブル構造だけを持った空のDataSetを作成する必要が
あると思ってその方法を考えていました。

他に方法がないかと思い考えてみまして、1つ思いついたのは
複写や更新と同じようにDataSetを作成し、内容をクリアして
その上で新規データを書き込むという方法なんですが・・・
どうもこれもおかしい気がしてさらに悩んでいます。。

片桐 継
会議室デビュー日: 2007/05/16
投稿数: 14
お住まい・勤務地: 東京
投稿日時: 2007-06-28 00:23
どうしてもDataSetを使わなければならない要件なのでしょうか?

特定できているキーのレコードから、キーだけが新しくなったレコードのコピーデータがデータベースに格納できれば良いのであれば、INSERT文書いてSQLを発行するほうが早いのでは……と思ったのですけれど。

DataSetでなければならない、ということであれば、
http://msdn2.microsoft.com/ja-jp/library/06t089d7(VS.80).aspx
とかが参考になるかと思います。
Googleでキーワード「DataSet 行追加」で検索すると色々と情報が出てきましたよ。




_________________
片桐 継(Tugu Katagiri)@わんくま同盟
http://blogs.wankuma.com/esten
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-06-28 21:36
すみません。昨日は子供を寝かせながら考え事をしていると、一緒に寝てしまっていました。

 片桐さんも書かれていますが、1件だけであれば、DataSet を使うこともないと思います。
逆に、今回の場合、DataSet を使おうとするから、余計にややこしくなっていると思います。

 仕様を誤解していたので、私が理解している仕様をまとめます。

マスタデータのメンテナンス機能である。
商品コードを指定して1件を特定した後、更新、削除する。
また、指定した1件を元に、新規に登録する機能を有する。←ここミソ


 DataSet を用いてデータの更新を行うとき、次のような流れになります。

データベースからデータを取得する。
ユーザに提示する。
ユーザが更新する。
変更がある行を取り出す。
変更内容に応じて、データベースに書き戻す。

 このうち、下2つについては、Update メソッドで自動的にやってくれます(下準備は必要)。

 私が誤解していたのは、2つの質問が別々だと思っていたこと、データは DataGrid で見せると思っていたことです。
データを、個々の TextBox で見せるということに気がついたとき、両方の質問が一致しました。

 では、どのようにするかですが。今、複写処理を、どのように作っているのでしょうか?
おそらく、更新処理と同じように作り、「新しい商品コードを書き戻す」ように作ってあるのではないでしょうか。書かれてあることからは、そのように理解しました。
(なので、コードではなく、処理内容を書いて欲しいと、あちこちで書いているのですが。)
もしそうなら、「ここミソ」としたところに注目。更新ではなく、新規作成と同じように作ります。

 で、「新規の場合は連結するためのDataSetをどのように作ればよいのか」がつながってきました。
この場合、DataAdapter.FillSchema を使います。これで、テーブル構成だけ、持ってこれます。
 新規の場合、こうしてスキーマを取得してから、DataTable.NewRow で新しい行を作成し、DataTable.Rows.Add で追加します。後は更新と同じです。
 複写の場合、更新と同じようにまずデータを取得します。次に、新規と同じように新しい行を作ります。取得した行から、新しい行へ、内容を転記します。そして、DataTable.Rows.Remove(At) で取得した行を捨てます。それから新しい行を追加します。
 DataTable.Rows.Remove(At) で削除するのは、DataRow.Delete で削除を「マークする」と、Update したときにデータベースから削除されるためです。ですから、データを本当に削除したいときは、DataRow.Delete を使います。
_________________
バニラミント
ベテラン
会議室デビュー日: 2005/05/27
投稿数: 58
投稿日時: 2007-07-01 09:34
片桐さん、Jittaさんレスありがとうございました。
いろいろ試行錯誤してて返答が遅れてすみません。

TO 片桐さん
>>どうしてもDataSetを使わなければならない要件なのでしょうか?
要件としてはないのですが、DataBindingsを使ってデータ連結を行って作るという
前提がありまして、それにはまずDataSetを使わなければと思って・・・
そこから悩みはじめた次第でして。
参考URLありがとうございました。今後の勉強に役立てたいと思います。

TO Jittaさん
>>仕様を誤解していたので、私が理解している仕様をまとめます。
すいません。ややこしい書き方になってしまいました。
まとめていただいた仕様通りです。

>>この場合、DataAdapter.FillSchema を使います。
こんな便利なものがあるとは知らなかったです。
まだまだ調べ方が足りないと実感しました。

教えていただいた方法を理解して実践してみたいと思います。
本当にありがとうございました。


1

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