VB.NETからAccessデータベースを更新する

VB.NET で MSAccess のデータベースをどうにかするシリーズ、一応今回で完結です! INSERT と UPDATE を実装していきますー。
関連記事
- DataGridViewへAccessのデータベースファイルを読み込む
- AccessDBテーブルの主キー情報を取得する
- DataGridViewに読み込んだDB情報を再取得する
- DataGridViewをセル編集したときの行数を格納する
- Accessのデータベースファイルへ書き込むための接続・切断
- Accessデータベースのレコードを削除する
- Accessデータベースを更新する ←NOW!
ガッツリ続き物になってしまいました…。過去の分と合わせて順番に読んでいただけると分かりやすいかと思います。
なるべく簡素に書いているので、例外処理は甘いと思われます。ご参考にする際は、ご自分の環境に合わせてご修正ください。
解説のためツギハギしちゃったので、最後の記事(7回め)に全コードまとめてあります。書いたときの環境
- Visual Studio 2010
- .NET Framework 4.0
です。
SQL文を生成する

今までの実装で、追加や変更したセルに色がついて該当行(ゼロから始まる)が格納されているはずです。ここで「保存」ボタンを押して走るコードを実装します。
Form2.vb
Button2のクリックイベントに書きます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
'### Form2.vb ### Public Class Form2 '略 '---------------------------------------------------- ' メソッド '---------------------------------------------------- '略 '---------------------------------------------------- ' Formイベント '---------------------------------------------------- '略 '---------------------------------------------------- ' Buttonクリックイベント '---------------------------------------------------- Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click '再読込ボタン(Button1)クリック時(略) End Sub Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click '保存ボタン(Button2)クリック時 '編集データが無かったら終了 If list.hasUpdateList = False And list.hasInsertList = False Then Exit Sub End If 'UPDATEのSQL文リストを取得 Dim sqlList As New List(Of String) sqlList = db.getUpdateSql(list.updateList) 'INSERTのSQLの文リストを取得 Dim sqlList2 As New List(Of String) sqlList2 = db.getInsertSql(list.insertList) 'UPDATEとINSERTのリストをマージ sqlList.AddRange(sqlList2) 'SQLを実行 If db.runSQL(sqlList) = True Then '成功したら '再読込 db.Dispose() Call setTable() 'メッセージ MessageBox.Show("変更を保存しました。") End If End Sub Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click '削除ボタン(Button3)クリック時(略) End Sub '---------------------------------------------------- ' DataGridViewイベント '---------------------------------------------------- '略 End Class |
getUpdateSql
という関数を使ってUPDATE文のリストを生成(32行目)、getInsertSql
という関数を使ってINSERT文のリストを生成(35行目)、その2つを合わせちゃいます(37行目)。
で、そのリストを持って汎用のrunSQL
へ(40行目)。
DBtable.vb
上で書いたgetInsertSql
やgetUpdateSql
関数を書きます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
'### DBtable.vb ### Imports System.Data.OleDb Class DBtable '略 '---------------------------------------------------- ' テーブルに関すること '---------------------------------------------------- '略 '---------------------------------------------------- ' SQL文生成に関すること '---------------------------------------------------- Public Function getDeleteSql(ByVal targetRow As Integer) As List(Of String) 'DELETE文生成(略) End Function Public Function getInsertSql(insertList As List(Of Integer)) As List(Of String) 'INSERT文生成 Dim list As New List(Of String) Dim strSQL As String 'INSERT If Not IsNothing(insertList) Then For Each targetRow As Integer In insertList 'INSERT句 strSQL = "INSERT INTO " & tableName & "(" 'INTO句 For targetColumn As Integer = 0 To dgv.Columns.Count - 1 If isAutoIncrement(targetColumn) = False Then 'オートインクリメントじゃない場合 strSQL &= " " & dgv.Columns(targetColumn).HeaderCell.Value & "," End If Next strSQL = strSQL.Remove(strSQL.Length - 1) '最後の一文字(,)を削除 'VALUES句 strSQL &= " ) VALUES(" For targetColumn As Integer = 0 To dgv.Columns.Count - 1 If isAutoIncrement(targetColumn) = False Then 'オートインクリメントじゃない場合 Dim fieldTxt As String = getFieldTxt(targetRow, targetColumn) '囲み文字を含めたフィールド文字列を生成 strSQL &= " " & fieldTxt & "," End If Next strSQL = strSQL.Remove(strSQL.Length - 1) '最後の一文字(,)を削除 strSQL &= " )" list.Add(strSQL) 'リストに追加 Next End If Return list End Function Public Function getUpdateSql(updateList As List(Of Integer)) As List(Of String) 'UPDATE文生成 Dim list As New List(Of String) Dim strSQL As String 'UPDATE文作成 If Not IsNothing(updateList) Then For Each targetRow As Integer In updateList 'UPDATE句 strSQL = "UPDATE " & tableName & " SET" 'SET句 For targetColumn As Integer = 0 To dgv.Columns.Count - 1 If isAutoIncrement(targetColumn) = False And isPrimaryKey(targetColumn) = False Then 'オートインクリメント&主キーじゃない場合 Dim fieldTxt As String = getFieldTxt(targetRow, targetColumn) '囲み文字を含めたフィールド文字列を生成 strSQL &= " " & dgv.Columns(targetColumn).HeaderCell.Value & "=" & fieldTxt & "," End If Next strSQL = strSQL.Remove(strSQL.Length - 1) '最後の一文字(,)を削除 'WHERE句 strSQL &= getWhereTxt(targetRow) 'WHERE句を足す list.Add(strSQL) 'リストに追加 Next End If Return list End Function Private Function getWhereTxt(ByVal targetRow As Integer) As String 'WHERE句生成(略) End Function Private Function getEncloseTxt(ByVal TypeName As String) As String '囲み文字の判定(略) End Function Private Function getFieldTxt(ByVal targetRow As Integer, ByVal targetColumn As Integer) As String 'フィールド文字列生成 Dim encloseTxt As String Dim fieldTxt As String Dim typeName = tableData.Columns(targetColumn).DataType.Name If dgv.Rows(targetRow).Cells(targetColumn).Value IsNot DBNull.Value Then 'Nullじゃない場合 encloseTxt = getEncloseTxt(typeName) fieldTxt = encloseTxt & dgv.Rows(targetRow).Cells(targetColumn).Value & encloseTxt Else If typeName = "Boolean" Then 'BooleanでNULL判定されたときはfalseにする fieldTxt = "false" Else fieldTxt = "NULL" End If End If Return fieldTxt End Function End Class |
19~52行目が、INSERT文をリスト型で返すgetInsertSql
という関数。insertList を参照しながら、追加のあった行のフィールド名を値をそれぞれ並べて、INSERT文を生成します。値は、囲み文字を含めた形を取得するgetFieldTxt
という関数を呼んでいます(40行目)。
54~80行目が、UPDATE文をリスト型で返すgetUpdateSql
という関数。updateList を参照しながら、変更のあった行を「フィールド名=値」という形にして、UPDATE文を生成します。ここでも、囲み文字を含めた値を取得するgetFieldTxt
関数を呼んでいます(67行目)。WHERE句は、DELETE のときにも使ったgetWhereTxt
関数も使ってます(73行目)。
両方から呼ばれてるgetFieldTxt
関数は90~107行目。値がなければ Null、あれば囲み文字が違うのでgetEncloseTxt
関数(前回作ったやつ)を呼び出したり、まぁいろいろやってます。
使ってみたら、DataGridView の新行かつ型が Boolean で何もセルを触らなかった場合、「false」でなく「NULL」と判定されてしまう現象が確認できたので、100~101行目で処理しています。他にも何かあったらここで設定したほうが良いかもしれません。
動作確認
動かしてみます。

中身を変えて「保存」ボタンを押すと、

出来た! …けど、あれ? INSERT した行が一番上になってる…。
調べてみると、こちらのページの最後の方にこうありました。
並び順を指定しなかった場合取得したレコードは予測不可能な順番で並んでいるということを覚えておいてください。
なお、並び順を指定する場合はSQL文でORDER BYを使用します。
(中略)
SQL Serverの場合は並び順を指定しなかった場合はクラスタードインデックス(つまり主キー)の順に自動的に整列します。つまり、このあたりの仕様はデータベースによって異なります。そういったことをこまごまと気にするのは大変なので順番が重要な場合はORDER BYを指定する癖をつけておきましょう。
なるほど。ちなみにこの VB で新しく追加したレコードを Access を起動して見てみたら、そちらでは一番下に追加されていましたので、DataGridView の仕様かもしれません。気になる方は ORDER BY で並び順もきちんと指定してあげるのが良さそうです。
こんな感じですが、一応、当初やりたかった機能は全て実装することが出来たので、これでこのシリーズは終了になります。需要は少ない気がしますが、どなたかのお役に立てたら光栄です。
全コード
7回に分けてツギハギしてきたので、ここで全部載せておきます。フォームのデザインは最初の記事にあります。
Form1.vb
1 2 3 4 5 6 7 8 9 10 11 12 |
'### Form1.vb ### Public Class Form1 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click Form2.Text = Button1.Text 'タイトルをテーブル名に Form2.Show() 'Fomr2を表示 End Sub Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click Form2.Text = Button2.Text 'タイトルをテーブル名に Form2.Show() 'Fomr2を表示 End Sub End Class |
Form2.vb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
'### Form2.vb ### Public Class Form2 Private Const FILE_NAME As String = "C:\test.accdb" Private db As DBtable Private list As TargetList Private dgv As DataGridView '---------------------------------------------------- ' メソッド '---------------------------------------------------- Private Sub setTable() 'DataGridViewにテーブル内容をセット db = New DBtable(Me.Text, FILE_NAME) 'DBtableインスタンス生成 db.setDataSource() 'データセット list = New TargetList 'TargetListインスタンス生成 dgv.CurrentCell = Nothing 'DataGridView1の選択解除 End Sub Private Sub undoValue() '元の値に戻す dgv.CurrentCell.Value = cellValue End Sub '---------------------------------------------------- ' Formイベント '---------------------------------------------------- Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles Me.Load 'フォームロード時 dgv = Me.DataGridView1 Call setTable() End Sub Private Sub Form2_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing 'フォームが閉じるとき '未保存データ確認 If list.hasUpdateList = False And list.hasInsertList = False Then Exit Sub End If If MessageBox.Show("未保存のデータがあります。フォームを閉じてよろしいですか?", "確認", MessageBoxButtons.OKCancel) <> 1 Then e.Cancel = True End If End Sub Private Sub Form2_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed 'フォームが閉じたとき db.Dispose() End Sub '---------------------------------------------------- ' Buttonクリックイベント '---------------------------------------------------- Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click '再読込ボタン(Button1)クリック時 db.Dispose() 'いったん破棄 Call setTable() End Sub Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click '保存ボタン(Button2)クリック時 '編集データが無かったら終了 If list.hasUpdateList = False And list.hasInsertList = False Then Exit Sub End If 'UPDATEのSQL文リストを取得 Dim sqlList As New List(Of String) sqlList = db.getUpdateSql(list.updateList) 'INSERTのSQLの文リストを取得 Dim sqlList2 As New List(Of String) sqlList2 = db.getInsertSql(list.insertList) 'UPDATEとINSERTのリストをマージ sqlList.AddRange(sqlList2) 'SQLを実行 If db.runSQL(sqlList) = True Then '成功したら '再読込 db.Dispose() Call setTable() 'メッセージ MessageBox.Show("変更を保存しました。") End If End Sub Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click '削除ボタン(Button3)クリック時 '未保存データ確認 If list.hasUpdateList = True Or list.hasInsertList = True Then MessageBox.Show("編集中のデータがあります。先に「保存」か「再読込」を行なってください。") Exit Sub End If 'どこも選択されていない場合 If dgv.CurrentCellAddress.X = -1 Then MessageBox.Show("削除したい行を選択してください。", "確認", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) Exit Sub End If '削除前確認 DataGridView1.CurrentRow.Selected = True '対象行をすべて選択 If MessageBox.Show("選択されている行のデータを削除します。よろしいですか?", "確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) <> 1 Then Exit Sub End If 'DELETEのSQL文リストを取得 Dim sqlList As New List(Of String) sqlList = db.getDeleteSql(dgv.CurrentRow.Index) 'SQLを実行() If db.runSQL(sqlList) = True Then '成功したら '再読込 db.Dispose() Call setTable() 'メッセージ MessageBox.Show("削除しました。") End If End Sub '---------------------------------------------------- ' DataGridViewイベント '---------------------------------------------------- Private errFlg As Boolean Private insertFlg As Boolean Private cellValue Private Sub DataGridView1_DataError(sender As Object, e As System.Windows.Forms.DataGridViewDataErrorEventArgs) Handles DataGridView1.DataError '編集でエラーが発生した時 If Not (e.Exception Is Nothing) Then MessageBox.Show(e.ColumnIndex + 1 & "列 " & e.RowIndex + 1 & "行目 のセルでエラーが発生しました。" & vbCrLf & vbCrLf & e.Exception.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) End If e.Cancel = False '値を戻す errFlg = True 'エラーフラグを立てる End Sub Private Sub DataGridView1_UserAddedRow(sender As Object, e As System.Windows.Forms.DataGridViewRowEventArgs) Handles DataGridView1.UserAddedRow '新しい行が追加された時 insertFlg = True End Sub Private Sub DataGridView1_CellBeginEdit(sender As Object, e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles DataGridView1.CellBeginEdit 'セル編集前 errFlg = False insertFlg = False cellValue = dgv.CurrentCell.Value '該当セルの値を格納しておく End Sub Private Sub DataGridView1_CellEndEdit(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit 'セル編集後 If errFlg = False Then 'オートインクリメントの列は変更不可 If db.isAutoIncrement(dgv.CurrentCell.ColumnIndex) = True Then MessageBox.Show("このセルはオートインクリメントなので変更できません", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) Call undoValue() If insertFlg = False Then Exit Sub '既存レコードだった場合はここで終了 End If '新規レコードだった場合 If insertFlg = True Then If list.inInsertList(dgv.CurrentRow.Index) = False Then 'INSERTリストチェック list.addInsertList(dgv.CurrentRow.Index) 'なければINSERTリストに追加 End If Else '既存レコードだった場合 If list.inInsertList(dgv.CurrentRow.Index) = False Then 'INSERTリストになければ '主キーなら If db.isPrimaryKey(dgv.CurrentCell.ColumnIndex) = True Then MessageBox.Show("このセルは主キーなので変更できません", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) Call undoValue() Exit Sub End If 'チェックして追加 If list.inUpdateList(dgv.CurrentRow.Index) = False Then 'UPDATEリストチェック list.addUpdateList(dgv.CurrentRow.Index) 'なければUPDATEリストに追加 End If End If End If '変更したセルに色をつける dgv.CurrentCell.Style.BackColor = Color.LavenderBlush End If End Sub End Class |
DBtable.vb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
'### DBtable.vb ### Imports System.Data.OleDb Class DBtable 'フィールド Private tableName As Object Private fileName As String Private dgv As DataGridView = Form2.DataGridView1 'コンストラクタ Sub New(tableName_ As Object, fileName_ As String) tableName = tableName_ fileName = fileName_ End Sub '---------------------------------------------------- ' テーブルに関すること '---------------------------------------------------- Private dbCnc As OleDbConnection Private dbAdp As OleDbDataAdapter Private tableData As DataTable Private primaryKeyArray() As DataColumn Public Sub setDataSource() 'テーブルデータ読込 tableData = getTableData("SELECT * FROM " & tableName & ";") 'データグリッドビューへバインド Dim bindingSource1 As New BindingSource() bindingSource1.DataSource = tableData dgv.DataSource = bindingSource1 'フィールド情報 primaryKeyArray = tableData.PrimaryKey '主キー情報を取得 Call setColorPrimaryKey() '主キーのカラムに色つけ End Sub Private Function getTableData(ByVal strSQL As String) As DataTable 'テーブルを接続 dbCnc = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; " & "Data Source=" & fileName) dbAdp = New OleDbDataAdapter(strSQL, dbCnc) dbAdp.MissingSchemaAction = MissingSchemaAction.AddWithKey '既定の情報と共に主キーメタデータも読み込む Dim table As New DataTable dbAdp.Fill(table) Return table End Function Public Sub Dispose() 'コネクション切断(なくてもいい気もする) dbAdp.Dispose() 'アダプター破棄 dbCnc.Dispose() 'コネクションを破棄 End Sub Private Sub setColorPrimaryKey() 'データグリッドビューの主キー列色を変える For i As Integer = 0 To primaryKeyArray.Length - 1 dgv.Columns(i).HeaderCell.Style.BackColor = Color.LemonChiffon '主キーのヘッダー色(.EnableHeadersVisualStyles=False にすること) Next End Sub Public Function isPrimaryKey(ByVal targetColumn As Integer) As Boolean '主キー列か判定 Dim checkFlg As Boolean For i As Integer = 0 To primaryKeyArray.Length - 1 If primaryKeyArray(i).Ordinal = targetColumn Then checkFlg = True Next Return checkFlg End Function Public Function isAutoIncrement(ByVal targetColumn As Integer) As Boolean 'オートインクリメント列か判定 Dim checkFlg As Boolean If tableData.Columns(targetColumn).AutoIncrement = True Then checkFlg = True Return checkFlg End Function Public Function runSQL(sqlList As List(Of String)) As Boolean 'テーブル情報の変更 Dim checkFlg As Boolean dbCnc.Open() 'コネクションオープン Dim dbCmd As OleDbCommand = dbCnc.CreateCommand Dim dbTrz As OleDbTransaction = dbCnc.BeginTransaction dbCmd.Connection = dbCnc 'コマンド接続 dbCmd.Transaction = dbTrz 'トランザクション開始 Try For Each strSQL As String In sqlList dbCmd.CommandText = strSQL 'リスト内のSQL文をセット dbCmd.ExecuteNonQuery() '実行 Next dbTrz.Commit() 'コミット(確定) checkFlg = True Catch ex As Exception MessageBox.Show(dbCmd.CommandText & vbCrLf & vbCrLf & ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) 'エラー内容表示 dbTrz.Rollback() 'ロールバック Finally dbCmd.Dispose() 'コマンドを破棄 dbCnc.Close() 'コネクションを閉じる End Try Return checkFlg End Function '---------------------------------------------------- ' SQL文生成に関すること '---------------------------------------------------- Public Function getDeleteSql(ByVal targetRow As Integer) As List(Of String) 'DELETE文生成 Dim list As New List(Of String) Dim strSQL As String 'DELETE句 strSQL = "DELETE FROM " & tableName 'WHERE句 strSQL &= getWhereTxt(targetRow) 'WHERE句を足す list.Add(strSQL) 'リストに追加 Return list End Function Public Function getInsertSql(insertList As List(Of Integer)) As List(Of String) 'INSERT文生成 Dim list As New List(Of String) Dim strSQL As String 'INSERT If Not IsNothing(insertList) Then For Each targetRow As Integer In insertList 'INSERT句 strSQL = "INSERT INTO " & tableName & "(" 'INTO句 For targetColumn As Integer = 0 To dgv.Columns.Count - 1 If isAutoIncrement(targetColumn) = False Then 'オートインクリメントじゃない場合 strSQL &= " " & dgv.Columns(targetColumn).HeaderCell.Value & "," End If Next strSQL = strSQL.Remove(strSQL.Length - 1) '最後の一文字(,)を削除 'VALUES句 strSQL &= " ) VALUES(" For targetColumn As Integer = 0 To dgv.Columns.Count - 1 If isAutoIncrement(targetColumn) = False Then 'オートインクリメントじゃない場合 Dim fieldTxt As String = getFieldTxt(targetRow, targetColumn) '囲み文字を含めたフィールド文字列を生成 strSQL &= " " & fieldTxt & "," End If Next strSQL = strSQL.Remove(strSQL.Length - 1) '最後の一文字(,)を削除 strSQL &= " )" list.Add(strSQL) 'リストに追加 Next End If Return list End Function Public Function getUpdateSql(updateList As List(Of Integer)) As List(Of String) 'UPDATE文生成 Dim list As New List(Of String) Dim strSQL As String 'UPDATE文作成 If Not IsNothing(updateList) Then For Each targetRow As Integer In updateList 'UPDATE句 strSQL = "UPDATE " & tableName & " SET" 'SET句 For targetColumn As Integer = 0 To dgv.Columns.Count - 1 If isAutoIncrement(targetColumn) = False And isPrimaryKey(targetColumn) = False Then 'オートインクリメント&主キーじゃない場合 Dim fieldTxt As String = getFieldTxt(targetRow, targetColumn) '囲み文字を含めたフィールド文字列を生成 strSQL &= " " & dgv.Columns(targetColumn).HeaderCell.Value & "=" & fieldTxt & "," End If Next strSQL = strSQL.Remove(strSQL.Length - 1) '最後の一文字(,)を削除 'WHERE句 strSQL &= getWhereTxt(targetRow) 'WHERE句を足す list.Add(strSQL) 'リストに追加 Next End If Return list End Function Private Function getWhereTxt(ByVal targetRow As Integer) As String 'WHERE句生成 Dim encloseTxt As String Dim whereTxt As String = "" For i As Integer = 0 To primaryKeyArray.Length - 1 '主キーの列番号をループ If i = 0 Then whereTxt = " WHERE " Else '主キーがふたつ以上ある場合 whereTxt &= " AND " End If Dim keyColumn As Integer = primaryKeyArray(i).Ordinal '主キーの列数 Dim TypeName As String = tableData.Columns(keyColumn).DataType.Name '主キーの型タイプ encloseTxt = getEncloseTxt(TypeName) '囲み文字を取得 whereTxt &= dgv.Columns(keyColumn).HeaderCell.Value & "=" & encloseTxt & dgv.Rows(targetRow).Cells(keyColumn).Value & encloseTxt Next Return whereTxt End Function Private Function getEncloseTxt(ByVal TypeName As String) As String '囲み文字の判定 Dim encloseTxt As String Select Case TypeName Case "String" encloseTxt = "'" Case "DateTime" encloseTxt = "#" Case Else encloseTxt = "" End Select Return encloseTxt End Function Private Function getFieldTxt(ByVal targetRow As Integer, ByVal targetColumn As Integer) As String 'フィールド文字列生成 Dim encloseTxt As String Dim fieldTxt As String Dim typeName = tableData.Columns(targetColumn).DataType.Name If dgv.Rows(targetRow).Cells(targetColumn).Value IsNot DBNull.Value Then 'Nullじゃない場合 encloseTxt = getEncloseTxt(typeName) fieldTxt = encloseTxt & dgv.Rows(targetRow).Cells(targetColumn).Value & encloseTxt Else If typeName = "Boolean" Then 'BooleanでNULL判定されたときはfalseにする fieldTxt = "false" Else fieldTxt = "NULL" End If End If Return fieldTxt End Function End Class |
TargetList.vb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
'### TargetList.vb ### Public Class TargetList 'フィールド Private updateList_ As List(Of Integer) Private insertList_ As List(Of Integer) 'ゲッター Public ReadOnly Property updateList() As List(Of Integer) Get Return updateList_ End Get End Property Public ReadOnly Property insertList() As List(Of Integer) Get Return insertList_ End Get End Property '---------------------------------------------------- ' updateListリストに関すること '---------------------------------------------------- Public Function hasUpdateList() As Boolean 'UPDATEリストが存在しているかチェック Dim checkFlg As Boolean = False If Not IsNothing(updateList_) Then checkFlg = True End If Return checkFlg End Function Public Function inUpdateList(ByVal targetRow As Integer) As Boolean 'UPDATEリストに既に行があるかチェック Dim checkFlg As Boolean = False If hasUpdateList() = False Then updateList_ = New List(Of Integer) Else For Each item As Integer In updateList_ If item = targetRow Then checkFlg = True Next End If Return checkFlg End Function Public Sub addUpdateList(targetRow As Integer) 'UPDATEリストへ追加 updateList_.Add(targetRow) End Sub '---------------------------------------------------- ' insertListリストに関すること '---------------------------------------------------- Public Function hasInsertList() As Boolean 'UPDATEリストが存在しているかチェック Dim checkFlg As Boolean = False If Not IsNothing(insertList_) Then checkFlg = True End If Return checkFlg End Function Public Function inInsertList(ByVal targetRow As Integer) As Boolean 'INSERTリストに既に行があるかチェック Dim checkFlg As Boolean = False If hasInsertList() = False Then insertList_ = New List(Of Integer) Else For Each item As Integer In insertList_ If item = targetRow Then checkFlg = True Next End If Return checkFlg End Function Public Sub addInsertList(targetRow As Integer) 'INSERTリストへ追加 insertList_.Add(targetRow) End Sub End Class |
拙いコードですが煮るなり焼くなり。お気づきの点があったら教えて下さい!
コメントは承認制ですので、反映までしばらくお待ち下さい。(稀にスパムの誤判定にて届かないこともあるようですので、必要な際はお問い合わせからお願い致します。)