- PR -

VB.NET 見出し行と明細行の同時取得と表示

1
投稿者投稿内容
ふらわー
常連さん
会議室デビュー日: 2008/01/11
投稿数: 33
投稿日時: 2008-02-04 18:29
VB.NETのWindowsアプリケーションを開発している初心者です。
よろしくお願いします。

いい件名が思いつかなかったので、件名にそぐう内容ではないかもしれませんがすいません。

結果セットに、例えばAテーブルに紐づくBテーブルのデータを埋め込ませる方法で悩んでいます。
ちょっと説明の仕方がわかりにくいと思いますが、イメージとしては売上見出し行があって売上明細をその次の行に埋め込ませたいという意味です。

以下に詳しい内容を示します。

Form1には、グレープシティ社のMultiRowSheetと検索実行ボタンがあります。

Oracleのデータベース上のテーブルの検索結果を一覧表示させようとしています。

テーブルの構成は以下の通りです。

T_売上
−−−−−−−−
NO
担当者CD
営業所CD
日付
金額


T_仕入
−−−−−−−−
NO
表示順
担当者CD
営業所CD
日付
金額

T_売上のNOに紐づくのがT_仕入のNOで、1対多の関係です。


まずT_売上の内容をデータセットに取得してみました。

ソースは以下の通りです。(抜粋です)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

Dim dr1 As OracleDataReader
Dim ds As New DS
Dim intCNT As Integer = 0
Dim tr As DS.DataTable1Row

Try
  'SQL取得と実行部分がここにあります。(省略しました)

Do While dr1.Read

tr = ds.DataTable1.NewDataTable1Row '新しい行の追加
tr.BeginEdit()     '編集開始

tr.EIGYO_CD = dr1.Item("NO").ToString
tr.TANTO_CD = dr1.Item("担当者CD").ToString
tr.NINUSI_CD = dr1.Item("営業所CD").ToString
tr.TORI_NM = dr1.Item("日付").ToString
tr.SYORI_NO = dr1.Item("金額").ToString

intCNT = intCNT + 1

tr.EndEdit() '編集終了
ds.DataTable1.Rows.Add(tr) '最後にデータセットに追加する

Loop

      以下省略

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

とここまでは問題なく表示できます。(当たり前ですが…)

その後、上記のデータセット内のNOに紐づくT_仕入のデータを上記のデータセット内に挿入して並べ替えしたいのです。
ソートはNO、表示順です。

どのような方法を使えばいいのでしょうか??

最初はSQL文でUNIONを使用し、T_売上とT_仕入の結果をつなげてみたのですがそれではちょっと問題がありました。
T_売上の日付とT_仕入の日付は必ずしも一致しておらず、日にちがずれるまたは入っていないことがあります。
これが終わったら次は検索させて表示させるようにするため、必ず同じNOのT_売上とT_仕入は紐づいているようにしておかないといけません。
T_売上ができるとT_仕入ができます。T_仕入のデータがない場合はあります。

データセットの値を利用し、1行ずつ読んでそのNOを検索条件としてT_仕入を検索しその結果を同じデータセットに挿入すると言うやり方も思いつきましたが、やり方がわかりませんでした。
この場合その都度DBに接続するので、効率が悪いとは思っています。

もっとスマートなやり方はないでしょうか?

大変困っていますので、お力を貸してください。

よろしくお願いします。
上総
大ベテラン
会議室デビュー日: 2006/06/22
投稿数: 107
投稿日時: 2008-02-04 19:59
引用:

スレ主さんの書き込み(2008-02-04 18:29)より
T_売上の日付とT_仕入の日付は必ずしも一致しておらず、日にちがずれるまたは入っていないことがあります。
これが終わったら次は検索させて表示させるようにするため、必ず同じNOのT_売上とT_仕入は紐づいているようにしておかないといけません。
T_売上ができるとT_仕入ができます。T_仕入のデータがない場合はあります。

データセットの値を利用し、1行ずつ読んでそのNOを検索条件としてT_仕入を検索しその結果を同じデータセットに挿入すると言うやり方も思いつきましたが、やり方がわかりませんでした。
この場合その都度DBに接続するので、効率が悪いとは思っています。


T_売上とT_仕入れをNOで紐付けると言う事ですが、T_仕入にデータがないものも含めて
出力するのであれば、下記SQLで問題無いと思います。

コード:

SELECT ALL
NO,
表示順,
担当者CD,
営業所CD,
日付,
金額
FROM (
SELECT ALL
NO,
0 AS 表示順,
担当者CD,
営業所CD,
日付,
金額
FROM T_売上
UNION ALL
SELECT ALL
NO,
表示順,
担当者CD,
営業所CD,
日付,
金額
FROM T_仕入
) T_明細
ORDER BY NO ASC
表示順 ASC;


データベースが指定されてませんでしたが、標準のSQLを使用出来るのであれば
上記SQLで問題ないと思います。(ACCESSはUNION ALLが使用出来ませんが)

コードのT_売上の表示順に0を指定していますが、T_仕入れの表示順より小さい値で
あれば何を指定しても問題ありません。(数値型の前提です)

T_売上の抽出条件にT_仕入にデータがあるものであれば、下記SQLで
コード:

SELECT ALL
NO,
表示順,
担当者CD,
営業所CD,
日付,
金額
FROM (
SELECT ALL
NO,
0 AS 表示順,
担当者CD,
営業所CD,
日付,
金額
FROM T_売上
WHERE NO IN
(
SELECT ALL
NO
FROM T_仕入
)
UNION ALL
SELECT ALL
NO,
表示順,
担当者CD,
営業所CD,
日付,
金額
FROM T_仕入
) T_明細
ORDER BY NO ASC
表示順 ASC;



[ メッセージ編集済み 編集者: 上総 編集日時 2008-02-04 20:13 ]
ふらわー
常連さん
会議室デビュー日: 2008/01/11
投稿数: 33
投稿日時: 2008-02-06 10:42
上総様

ありがとうございました。
返信遅くなりました。

確かに上総さんの提示していただいたコードで全てのデータを表示する場合は問題ないと思うのですが、このデータを日付で検索した場合のことを考えると本当にできるか疑問なのです。

「T_売上の日付とT_仕入の日付は必ずしも一致していない」というところがポイントで、日付検索してこのデータを表示したい場合には、T_売上が持っている日付で検索しT_仕入のデータも一緒に表示させたいのです。
うまく説明ができないので、例を示します。
下記のようなデータがあったとします。
ずれてしまってうまく表示されないですが、T_売上には2件のデータ(NO.0001とNO.0002)、T_仕入には3件のデータ(NO.0001〜NO.0003)があるとします。

T_売上
−−−−−−−−
NO     0001 | 0002
担当者CD  0A | 0B
営業所CD  01 | 03
日付    2008/01/08 | 2008/01/31
金額    50000 | 10000


T_仕入
−−−−−−−−
NO     0001    | 0001 | 0001
表示順   0  | 1 | 2
担当者CD  0A | 0A | 0A
営業所CD  01 | 01 | 01
日付    2008/01/08 | 2008/01/11 | 2008/01/20
金額    20000 | 10000 | 20000

T_売上のNO.0001にはT_仕入の3つのデータが紐づきます。
結果をMultiRowSheetに表示すると以下のようになります。


NO 担当者CD 営業所CD 日付 金額 区分
0001 0A 01 2008/01/08 50000 売上 ←T_売上の1番目のデータ
0001 0A 01 2008/01/08 20000 仕入 ←T_仕入の1番目のデータ

0001 0A 01 2008/01/11 10000 仕入 ←T_仕入の2番目のデータ

0001 0A 01 2008/01/20 20000 仕入 ←T_仕入の3番目のデータ

0002 0B 03 2008/01/31 10000 売上 ←T_売上の2番目のデータ

ここで日付検索をします。(日付検索の対象はT_売上の日付です)
例えば「日付 = "2008/01/08"」の場合にMultiRowSheetに表示させたい結果は


NO 担当者CD 営業所CD 日付 金額 区分
0001 0A 01 2008/01/08 50000 売上 ←T_売上の1番目のデータ
0001 0A 01 2008/01/08 20000 仕入 ←T_仕入の1番目のデータ

0001 0A 01 2008/01/11 10000 仕入 ←T_仕入の2番目のデータ

0001 0A 01 2008/01/20 20000 仕入 ←T_仕入の3番目のデータ

上記のようになってほしいのです。
上総さんに教えていただいたやり方だと

NO 担当者CD 営業所CD 日付 金額 区分
0001 0A 01 2008/01/08 50000 売上 ←T_売上の1番目のデータ
0001 0A 01 2008/01/08 20000 仕入 ←T_仕入の1番目のデータ

このようになって、T_仕入の「日付 = "2008/01/08"」のデータしか表示されないのではないかと思います。
T_仕入の日付はある一定の法則に基づいているわけではないですが、T_売上の日付データ以降の日付で、T_売上のデータごとにT_仕入のデータが数件ある場合や一件もデータがない場合もあります。
またT_仕入の日付がNULLの場合もあります。

このような場合でもうまくいくものでしょうか??
最初からきちんと例を示していればよかったです。
申し訳ありません。

ちょっと長くなってしまいましたが、よろしくお願いいたします。
上総
大ベテラン
会議室デビュー日: 2006/06/22
投稿数: 107
投稿日時: 2008-02-06 11:08
引用:

スレ主さんの書き込み(2008-02-06 10:42)より
ここで日付検索をします。(日付検索の対象はT_売上の日付です)
例えば「日付 = "2008/01/08"」の場合にMultiRowSheetに表示させたい結果は



グリッド上で検索ですか?
SQLでの対応だとこうなります。

コード:

SELECT ALL
NO,
表示順,
担当者CD,
営業所CD,
日付,
金額
FROM (
SELECT ALL
NO,
0 AS 表示順,
担当者CD,
営業所CD,
日付,
金額
FROM T_売上
WHERE 日付 = "2008/01/08"
UNION ALL
SELECT ALL
NO,
表示順,
担当者CD,
営業所CD,
日付,
金額
FROM T_仕入
WHERE NO IN
(
SELECT ALL
NO
FROM T_売上
WHERE 日付 = "2008/01/08"
)
) T_明細
ORDER BY NO ASC
表示順 ASC;



グリッド上で検索を行うのであれば、「表示順 = 0(つまりはT_売上のデータ)で
且つ日付 = 指定した日付」のデータを検索し、取得したNoでフィルタリングをかける
方法になりますかね。

引用:

スレ主さんの書き込み(2008-02-06 10:42)より
T_仕入の日付はある一定の法則に基づいているわけではないですが、T_売上の日付データ以降の日付で、T_売上のデータごとにT_仕入のデータが数件ある場合や一件もデータがない場合もあります。
またT_仕入の日付がNULLの場合もあります。


上記の前提条件に追加でT_売上の日付データにNULLがなければという条件であれば、
SQLやグリッドの設定で上手くいくと思います。

[ メッセージ編集済み 編集者: 上総 編集日時 2008-02-06 11:11 ]
1

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