ここから本文です

VB2008 Insertのループ処理について

sdi********さん

2009/4/411:04:36

VB2008 Insertのループ処理について

お世話様です。
現在、VB2008にて、DataGridViewに入力した内容を、Insertで登録処理をするという作業を行っているのですが、変わった現象が起きてしまうのです。
まず、ボタンクリックのイベントで、DataGridViewの内容を一行づつ取り込み、Insertのループを行うと言うものなのですが、
DataGridViewにある列は、'日付','出勤時間',退社時間','~~と続くのですが、日付だけしか一行づつ取り込めず、それ以外の列項目は、値の入っている列までしか取り込めないんです。
たとえば、二行目まで値を入れ、三行目からはすべてのCellをNullの状態にしてInsertのループをかけると、二行目にしか入らない値が、三行目以降まで続いてしまうんです。これってどういうことでしょうか、、、ちなみに日付だけはきちんとInsertされるのです。どなたかお分かりになる方いらっしゃらないでしょうか。
ちなみにこれがソースです。

For r As DataGridViewRow in DataGridView1.Rows
日付 = DataGridView1(0, r.Index).Value
If IsDBNull (DataGridView1(9, r.Index).Value) = False Then
出勤時間 = DataGridView1(9, r.Index).Value
Else If IsDBNull(DataGridView1(5. r.Index).Value) = False Then
出勤時間 = "0"
End If
'列が多いので、省略します。
'ここからInsert
sql = "Insert into Time Seet"
sql &= "Values ("
sql &= "'" & 日付 & "'"
:
:
Next r
という形です。列が長いので、だいぶ省略しましたので伝わりにくいかと思いますが、よろしくお願いします。

補足>ktn122002さん
DBでの日付はDATE型です。NOT NULLと設定しておりますので、DataGridView内でも、日付は必ず入力されるように
作成しておりますので、登録の際、日付がNULLになることはありません。ただ、出勤時間や退社時間などに関しては、NUMBER
型としてテーブルを作成しております。

閲覧数:
1,506
回答数:
3
お礼:
50枚

違反報告

ベストアンサーに選ばれた回答

ktn********さん

編集あり2009/4/417:03:25

こういうことですか?単純にDataGridViewの行をDBへ登録するということなら
以下のような感じでやってみては?条件文については省いていますので
御自身でがんばってください。Forの使い方が不明なので私が
やる場合のことを前提でコードを示します。私は for eachを使用しています。


Dim r As DataGridViewRow
For Each r In Me.dataGridView1.Rows

'説明
'cc(3)で文字列変数の配列を作成します。
'質問の内容でいけば、日付・開始・終了という3つの
'セルがあるということなので、一応、このコードの中では
'テーブルには3つの列を作成しています。
'テーブル内部を左側の列から日付・開始・終了の順番に
'設定しています。cells(x)のxに相当する箇所が、行の中の
'セルアドレスです。(0)が日付、(1)が開始、(2)が終了になります。

Dim cc(3) As String
cc(0) = Convert.ToString(r.Cells(0).Value)
cc(1) = Convert.ToString(r.Cells(1).Value)
cc(2) = Convert.ToString(r.Cells(2).Value)
Dim s1 As String = "insert into テーブル名 values('" + cc(0) + "','" + cc(1) + "','" + cc(2) + "')"
Dim sss As New SqlCommand(s1, s)
sss.ExecuteNonQuery()

Next r
s.Close()

→訂正します。DB構成をしているソフトで、日付の部分に該当する列のデータ型は
何ですか?SQLServerなんかを使用していると、dataTime型にしているとNULLにした
場合、1900・・・・とか言うようになると思いますが、そのことをおっしゃっているのでしょうか?
文字列型(varchar)にすると、恐らくNULLになると思いますが・・。

質問した人からのコメント

2009/4/6 10:40:45

ご回答くださった皆さん、ありがとうございます!ktn122002さんのサンプルコードを元にソースを書き直しまして、どうにか思い通りの動作ができるようになりました。

ベストアンサー以外の回答

1〜2件/2件中

並び替え:回答日時の
新しい順
|古い順

pat********さん

2009/4/420:13:46

そもそもループでデータをインサートする手法自体見直した方が良いと思います。
(VB6の手法だと思います、1SQLを発行する度に、データベースサーバー側でSQLのコンパイルが走り、
処理が遅くなります。)

System.Data.SqlClient(Oracleの場合はOracleClient).DataAdapterのUpdate()メソッドを使用すれば、
DATASETを使用して、一括でデータを挿入することが出来、データベースとのパフォーマンスも良いです。

(DATASETは内部に、ステータスを持っていて、DATASET内のデータが挿入、更新、削除されたかを持っています。)
例:
Dim sql_con As New Data.SqlClient.SqlConnection(接続文字列)
Dim sql_ad As New Data.SqlClient.SqlDataAdapter
Dim instcmd As New Data.SqlClient.SqlCommand

selectcmd.CommandText = "Insert into Time Seet VALUES(@Date)"

Dim sqlparam As New Data.SqlClient.SqlParameter

sqlparam.ParameterName = "@Date"
sqlparam.SourceColumn = "DataSetのカラム名"

ad.Update(データセット,"テーブル名")

ttkai00さん

2009/4/412:47:36

ご提示のコードだけでは何とも言えません。デバッガで試してみればすぐに解決するような気がしますけど。

予想で答えてみると、「出勤時間」という変数は If~Else If で設定していますが、このどちらも False だった場合に代入されないように見えます。(Else If ではないただの Else 句がないため)「出勤時間」変数がループの外側で定義されているとすると、2行目のループで設定されて3行目以降もそのままの値を保持し続けているんじゃないでしょうか?

本題と関係ないですが、SQLを文字列連結で作成するのはやめたほうがいいと思いますよ。セキュリティの問題、パフォーマンスの問題から、パラメータクエリを使う方がよいです。

ループの外側でパラメータクエリを作成して、ループの中ではパラメータの設定とSQLの実行のみにすればよいです。

あわせて知りたい

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる