- PR -

datagridで行の値を入れ替えたい

投稿者投稿内容
じいじ
大ベテラン
会議室デビュー日: 2003/11/11
投稿数: 223
投稿日時: 2004-01-22 09:35
初めて投稿します。VB.NET+ACCESS+Windowsフォームを使っている初心者です。
datagridのカレント行を「上へ」ボタンを押すと、上の行と入れ替わるものを作りたいのですが、「これとこれをこうするとできるよ」程度でいいので誰かヒントをください。
じいじ
大ベテラン
会議室デビュー日: 2003/11/11
投稿数: 223
投稿日時: 2004-01-22 14:11
次のようなことをしたいのです。

before after        しかし
1 1          1    
2 2 2
3 * 4 * 3
* 4 3 3
5 5 5 となってしまいます。

* はカレント行のマークです。

DataTableやDataViewで要素を入れ替えて、データベースに書き込んで、データセットをクリアしてから再度読み込んでいますが、うまくいきません。

上の「しかし」の状態でカレント行を削除すると、「3」の行2つとも削除されてしまいます。





Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-01-22 14:43
引用:

じいじさんの書き込み (2004-01-22 14:11) より:

次のようなことをしたいのです。
コード:

before after        しかし
1 1          1    
2 2 2
3 * 4 * 3
* 4 3 3
5 5 5 となってしまいます。


* はカレント行のマークです。

DataTableやDataViewで要素を入れ替えて、データベースに書き込んで、データセットをクリアしてから再度読み込んでいますが、うまくいきません。

上の「しかし」の状態でカレント行を削除すると、「3」の行2つとも削除されてしまいます。


例えば、DataViewに「表示順」のカラムを追加し、その「表示順」を入れ替える、とか。

えっと、「入れ替え」のためには、余分に1つ、変数が必要です。昔、swapとか言う関数か何かがなかったっけ?

a(10)配列の、8番目と9番目を入れ替えるには、
tmp = a(7)
a(7) = a(8)
a(8) = tmp
とします。同じことをやってください。

[ メッセージ編集済み 編集者: Jitta 編集日時 2004-01-22 14:43 ]
じいじ
大ベテラン
会議室デビュー日: 2003/11/11
投稿数: 223
投稿日時: 2004-01-22 15:14
Jittaさん、私のメッセージを直してくださってありがとうございます。

表示順のカラムも考えましたが、もっとスマートに直感で操作できるようにしたいのです。

要素の入れ替えは、教示通りのいわゆるswap(そしてまさにtmp)を使って入れ替えています。

この機能は絶対に必要というわけではありませんが、detagridに入力するデータはマスターデータで、たとえば顧客データを入力するとき、コンボボックスの上部によく入力するデータが集まっていれば効率的だと思ったからです。

あと1ヶ月ぐらいあーだのこーだのとやってみます。

Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-01-22 15:44
引用:

じいじさんの書き込み (2004-01-22 15:14) より:

detagridに入力するデータはマスターデータで、たとえば顧客データを入力するとき、コンボボックスの上部によく入力するデータが集まっていれば効率的だと思ったからです。


 なるほど。では、よく入力するものを、自動で上に表示してしまえば、どうですか?

 Oracleなので、Accessにはちょっと手直しが必要かと思いますが。

SELECT s.NAME, NVL(d.c2, 0) FROM マスタテーブル mst
LEFT JOIN (SELECT マスタへの外部参照 c1, COUNT(マスタへの外部参照) c2
FROM データテーブル GROUP BY マスタへの外部参照) dt
ON mst.ID = dt.c1
ORDER BY 2 DESC


まず、データテーブルからマスタテーブルへ外部参照している項目と、使用している数を求め、これを仮表dtとします。
 SELECT マスタへの外部参照 c1, COUNT(マスタへの外部参照) c2
 FROM データテーブル GROUP BY マスタへの外部参照) dt

マスタテーブルと仮表を左外部結合し、名称とソートのために使用数を取り出します。
 SELECT s.NAME, NVL(d.c2, 0) FROM マスタテーブル mst
 LEFT JOIN () ON mst.ID = dt.c1

最後に、使用数(2番目のカラム)でソートします。
 ORDER BY 2 DESC

NVL(a, b)はOracle用の関数で、aの値がnull(この場合は使われていない)ならばbの値で置き換えます。Oracleではnullはソートの対象にならず先頭に表示されるので、こうしています。
#いや、他の方法もあるんだけどね
NAL-6295
ぬし
会議室デビュー日: 2003/01/26
投稿数: 966
お住まい・勤務地: 東京
投稿日時: 2004-01-22 16:14
引用:

じいじさんの書き込み (2004-01-22 15:14) より:
Jittaさん、私のメッセージを直してくださってありがとうございます。

表示順のカラムも考えましたが、もっとスマートに直感で操作できるようにしたいのです。

要素の入れ替えは、教示通りのいわゆるswap(そしてまさにtmp)を使って入れ替えています。

この機能は絶対に必要というわけではありませんが、detagridに入力するデータはマスターデータで、たとえば顧客データを入力するとき、コンボボックスの上部によく入力するデータが集まっていれば効率的だと思ったからです。

あと1ヶ月ぐらいあーだのこーだのとやってみます。





一応、例にあるような事は下記のコードで出来ました。
そういう事を言ってるんじゃ無いって時はごめんなさい。

コード:

if(dataGrid1.CurrentRowIndex == 0) return;

DataTable dt = (DataTable)dataGrid1.DataSource;
object[] obj = dt.Rows[dataGrid1.CurrentRowIndex].ItemArray;
object[] obj2 = dt.Rows[dataGrid1.CurrentRowIndex-1].ItemArray;
dt.Rows[dataGrid1.CurrentRowIndex].ItemArray = obj2;
dt.Rows[dataGrid1.CurrentRowIndex-1].ItemArray = obj;




ここから追加

すいません、VB.NETでしたね。
下記のようになると思います。
また、推測ですが、参照型を新しい変数に代入しても、参照している場所はどちらも一緒なので
結果的に3が二つになってしまうような事が起こったのではないでしょうか?

コード:


If dataGrid1.CurrentRowIndex = 0 Then
Exit Sub
End If

Dim dt As DataTable = CType(dataGrid1.DataSource, DataTable)
Dim obj() As Object = dt.Rows(dataGrid1.CurrentRowIndex).ItemArray
Dim obj2() As Object = dt.Rows(dataGrid1.CurrentRowIndex - 1).ItemArray
dt.Rows(dataGrid1.CurrentRowIndex).ItemArray = obj2
dt.Rows(dataGrid1.CurrentRowIndex - 1).ItemArray = obj






[ メッセージ編集済み 編集者: NAL-6295 編集日時 2004-01-22 16:34 ]
じいじ
大ベテラン
会議室デビュー日: 2003/11/11
投稿数: 223
投稿日時: 2004-01-22 16:14
あの〜 初心者なんですけど・・・・

今までやってみた(考えた)ことは、
1.datagridのカレント行に空白行を挿入し、そこへ入力する。
2.テキストボックスに入力して挿入ボタンを押すと、datagridのカレント行に挿入される。

ですけど、全滅でした。
じいじ
大ベテラン
会議室デビュー日: 2003/11/11
投稿数: 223
投稿日時: 2004-01-26 12:21
NAL-6295さんの方法で、DataTable上(?)での値の入れ替えはできましたが、
それをデータベースへ書き込んで、再度読み込んで表示すると、今までと同じように、
同じ値になってしまいます。
書き込む部分は

Me.BindingContext(dataset, datatable).EndCurrentEdit()
Me.OleDbDataAdaptre.Update(dataset, datatable)
Me.dataset.Clear()
Me.OleDbDataAdapter.Fill(dataset)

とやっています。

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