- PR -

DataSetのDataTableのリレーションについて

1
投稿者投稿内容
ふらわー
常連さん
会議室デビュー日: 2008/01/11
投稿数: 33
投稿日時: 2008-02-21 13:04
いつもお世話になっております。

VB.NET、Oracleを使用したWindowsアプリを開発中の初心者です。
とても初歩的な質問かもしれませんが、よろしくお願いします。

帳票出力アプリケーションを作成中です。
フォームに絞り込み条件を入れ、作成するという流れのものでデータの取得にデータセットを使用しています。
SQL発行を2回している関係で、2つのデータテーブル(DataTable1とDataTable2)があります。
それをデザイナでそれぞれのコード列主キーを設定し、リレーションを張りました。
DataTable2の計算列にDataTable1で取得した同じコードである数値の列を利用して、DataTable2に値を入れたいのですがどのようにすればいいかわかりません。
リレーションのやり方についてはたくさん載っていたのですが、そのデータを個別に利用するやり方まではわかりませんでした。
データテーブルの構成は以下の通りです。

DataTable1
コード[CD]
数値1[SU1]
数値2[SU2]

DataTable2
コード[CD]
名前[NAME]
数値3[SU3]
合計[TOTAL]

DataTable2の合計列に、DataTable1の数値1と数値2とDataTable2の数値3のデータを入れたいです。
以下にコードを一部抜粋しました。
DataTableに値をセットしているところです。

Dim dr As OracleDataReader
Dim tr As DS.DataTable1Row
Dim tr2 As DS.DataTable2Row

tr = ds.DataTable1.NewDataTable1Row '行追加
tr.BeginEdit() '編集開始
tr1.CD = dr.Item("コード").ToString
tr1.SU1 = dr.Item("数値1").ToString
tr1.SU2 = dr.Item("数値2").ToString
tr1.EndEdit() '編集終了
ds.DataTable1.Rows.Add(tr1) 'データセットに追加する

'ここのコードは省略しています。

tr2 = ds.DataTable2.NewDataTable2Row
tr2.BeginEdit()
tr2.CD = dr.Item("コード").ToString
tr2.SU3 = dr.Item("数値3").ToString

tr2.TOTAL = Convert.ToInt32(tr1.SU1) + Convert.ToInt32(tr1.SU2)
↑☆ここをなんとかしたいです。

tr2.EndEdit() '編集終了
ds.DataTable2.Rows.Add(tr2) 'データセットに追加する


DataTable2の合計列にデータを入れる時に、DataTable1の値を見たいのですが・・・
上記のコードではどの列を見るのかわからないですよね。。。
それはわかっているのですが、どのように同じコードの列を見たらいいのかさっぱりわかりません。

どうかお力を貸してください。
よろしくお願いします。
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2008-02-21 14:33
リレーションの方向がどっちを向いているのか分かりませんが、
親から子を取得する場合は、DataRow.GetChildRows()
子から親をたどる場合は、DataRow.GetParentRow()で行が取得できます。
ふらわー
常連さん
会議室デビュー日: 2008/01/11
投稿数: 33
投稿日時: 2008-02-21 16:18
結局DataTableのSelectでコード検索をし、データを取得する方法にしました。
DataTableのリレーションを張った意味があまりなかったのですが・・・
NAL-6295
ぬし
会議室デビュー日: 2003/01/26
投稿数: 966
お住まい・勤務地: 東京
投稿日時: 2008-02-21 16:50
NAL-6295です。

DataColumn.Expressionプロパティ
http://msdn2.microsoft.com/ja-jp/library/system.data.datacolumn.expression(VS.85).aspx

を利用すれば、計算できたと思いますよ。


追記:サンプルはっておきます。
太字の部分がポイントです。
コード:

Dim 親テーブル As New DataTable
親テーブル.Columns.Add(New DataColumn("番号"))
親テーブル.Columns.Add(New DataColumn("数量", GetType(Decimal)))

For 番号 As Integer = 1 To 10
Dim 新規行 As DataRow = 親テーブル.NewRow()
新規行("番号") = 番号
新規行("数量") = 番号 * 100
親テーブル.Rows.Add(新規行)
Next

Dim 子テーブル As New DataTable
子テーブル.Columns.Add(New DataColumn("番号"))
子テーブル.Columns.Add(New DataColumn("数量", GetType(Decimal)))
子テーブル.Columns.Add(New DataColumn("数量計", GetType(Decimal)))

For 番号 As Integer = 1 To 10
Dim 新規行 As DataRow = 子テーブル.NewRow()
新規行("番号") = 番号
新規行("数量") = 番号 * 100
子テーブル.Rows.Add(新規行)
Next

Dim ds As New DataSet
ds.Tables.Add(子テーブル)
ds.Tables.Add(親テーブル)

Dim 番号でリレーション As New DataRelation("サンプル", 親テーブル.Columns("番号"), 子テーブル.Columns("番号"))

親テーブル.ChildRelations.Add(番号でリレーション)
子テーブル.Columns("数量計").Expression = "数量 + Parent.数量"

For Each 現在行 As DataRow In 子テーブル.Rows
Console.WriteLine(String.Format("番号:{0} 数量計:{1}", 現在行("番号"), 現在行("数量計")))
Next




[ メッセージ編集済み 編集者: NAL-6295 編集日時 2008-02-21 20:50 ]
むーみん
常連さん
会議室デビュー日: 2005/06/23
投稿数: 41
投稿日時: 2008-02-21 18:37
こんにちは。

DataTable2の、コード列が主キーに設定してあり、そのコードで検索するということであれば、findメソッドを使用すればいいのではないかと思います。

引用:

tr2.TOTAL = Convert.ToInt32(tr1.SU1) + Convert.ToInt32(tr1.SU2)
↑☆ここをなんとかしたいです。



の行を、

コード:

Dim key As Object = tr1.CD
' tr1.CDをキーにDataTable2から該当するコードの行を取得します。
Dim row As DataRow = ds.DataTable2.Rows.Find(key)
' 検索できなかったときのために条件分岐
if not row is nothing then
tr2.TOTAL = Convert.ToInt32(row.SU1) + Convert.ToInt32(row.SU2) + Convert.ToInt32(tr2.SU3)
else
tr2.TOTAL = Convert.ToInt32(tr2.SU3)
end if



※ちなみに、質問内容とは関係ないのですが、数値項目を文字列型で定義されているのかなと、ちょっと気になりました。

こんな感じに書き換えればだいじょぶなのではないかなと、思います。

ふらわーさんの質問されている処理内容だと、わたしはわざわざリレーションを組むメリットを感じないですが、リレーションを利用しているのであれば、かずくんさんのおっしゃるように、DataRow.GetChildRowsメソッドを利用しても、結果としては同じように処理が実現できると思います。findメソッドはリレーションとは関係なく主キー項目が設定されていれば使用できます。

お役に立てたらいいです。

[ メッセージ編集済み 編集者: むーみん 編集日時 2008-02-21 18:39 ]
1

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