続いて、更新登録機能を加えてみます。

一覧参照機能だけでなく、テーブル更新機能も加えてみます。
データベース環境は前ページと同じです。   前ページのサンプルを実行されている方は、そのままこのページもお試しいただけます。
そうでない方はまず、前ページのサンプルでデータベース環境が動作することを確認して下さい。

なお、現在のサンプルはDPI制御を行なっていませんので、96DPI以外で表示させると、このページの画面サンプルとは異なる表示になる場合があります。

実行画面はこのようになりました。

ACCDBの説明はこのページの最後に用意してあります。

配属一覧のサンプル
(画像をクリックすると、このページのサンプルがダウンロードできます)

一覧表示の機能は前ページと同じですが、これに加えて「行」を選択するとこのように「配属情報の登録・変更」の画面がポップアップ表示されます。 このサンプルではソースコードの提示を行なう関係で機能を複雑にできないということがあり、配属情報の追加や削除はできません。登録されている配属情報の部署や役職の変更のみができるようになっています。
この登録変更画面は、当初は一覧画面の中央に表示されますが、移動させると別の一覧の行から起動される場合に以前の位置に表示されるようになっており、一覧画面を閉じるまで継続されます。
「登録」ボタンは当初は不活性ですが、部署か役職を変更すると活性化してクリックできるようになります。

一覧表示・詳細登録フォームの動作説明です。

※上から下に向かって時系列で内部動作を含めて主要な動作を説明します。

配属一覧のサンプル

本ページの最初に提示している画像で後ろに見えている一覧表示画面がこの表では左側の「一覧表示フォーム」、手前に見えている小さい画面が右側の「詳細登録フォーム」として説明しています。
プログラムを起動した時点では「一覧表示フォーム」が起動され、「フォーム起動初期動作」が実行されます。これで配属情報の一覧表示までが行なわれます。 以降はユーザーの操作がなければ何も動きません。




ここでユーザーが「行」を選択(クリックするか↑↓キーで反転行を移動させてEnterキー打鍵)すると 選択行の「配属情報の登録・変更」の画面がポップアップ表示されますが、この表では右側の「詳細登録フォーム」が起動されてその動作が実行されるわけです。
内部的には「詳細登録フォーム」が起動される時に「一覧表示フォーム」側から「社員番号」「配属開始日」がプロパティで引き渡され、「詳細登録フォーム」で表示される内容が決定されます。
「詳細登録フォーム」ではまず、「一覧表示フォーム」で選択された行の内容を表示させた後、ユーザーの変更作業を待った後に「登録」ボタンがクリックされたら変更内容をデータベースに更新し、 処理結果(更新有無)を「一覧表示フォーム」に通知するという動作になっています。




本ページではこういった画面遷移と実際のデータベースアクセスの記述切り分けの説明に傾注するため、「新規登録」は扱っていません。「新規登録」は次ページで説明します。




それでは、ソースコードの説明に移ります。ソースコードも「一覧表示フォーム」、「詳細登録フォーム」に分かれています。

まずは一覧表示フォームのソースコードです。
上の画像の後ろ側の一覧表示フォームのソースコードです。

'***************************************************************************************************
'   配属一覧サンプル②(一覧表示)                             frmGetMdbDataTest01(Form)
'
'   作成者:井上治  URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
' 変更日付 Rev     変更履歴内容-------------------------------------------------------------------->
' 17/01/15(1.0.0.0)新規作成
' 17/01/22(1.0.1.0)更新登録画面追加に伴う修正
' 17/01/29(1.0.2.0)ダブルクリック抑制処置の共通クラス化対応
' 18/05/07(1.0.3.0)DataGridViewのスクロールバー表示不正の対応、初期処理をNewに移動させる対応
'***************************************************************************************************
Imports System.IO
Public Class frmGetMdbDataTest02
    '===============================================================================================
    Private Const g_cnsTitle As String = "配属一覧サンプル②"
    Private Const g_cnsDGVColumnMAX As Integer = 5          ' DataGridView最大カラム(表示)
    '-----------------------------------------------------------------------------------------------
    ' 背景色
    Private ReadOnly g_colorRetire As Color = Color.FromArgb(220, 220, 220) ' 退職色(薄灰)
    '-----------------------------------------------------------------------------------------------
    ' 共通クラス
    Private g_objAboutMDB As clsAboutMDB2                   ' データベースI/Oクラス(MDB用)
    Private g_objAboutWindow As clsAboutWindow1             ' ウィンドウ制御関連クラス
    Private g_objAboutDGV As clsAboutDataGridView1          ' DataGridView制御関連クラス
    Private g_objOmitDoubleClick As clsOmitDoubleClick2     ' ダブルクリック抑制クラス
    ' 詳細登録フォーム
    Private g_objSYOUSAI_Form As dlgGetMdbDataTest02 = Nothing ' 詳細登録フォーム
    '-----------------------------------------------------------------------------------------------
    ' 一覧表示用抽出SQL文共通部
    Private g_strSQL_Base As String = ""                    ' 抽出SQL文共通部
    '-----------------------------------------------------------------------------------------------
    ' デフォルトのカラム幅
    Private g_tblDefaultColumnWidth() As Integer            ' カラム幅テーブル

    '***********************************************************************************************
    ' ■■■ 初期化 ■■■
    '***********************************************************************************************
    '* 処理名 :New
    '* 機能  :初期化
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(なし)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2018年05月07日
    '* 作成者 :井上 治
    '* 更新日 :2018年05月07日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Public Sub New()
        '-------------------------------------------------------------------------------------------
        ' ※Windowsフォームデザイナ初期化(必須)
        Call InitializeComponent()
        ' フォームデザイナモード時は以下をスキップする
        If Me.DesignMode Then Exit Sub
        '-------------------------------------------------------------------------------------------
        ' データベースI/Oクラスの初期化
        g_objAboutMDB = New clsAboutMDB2(Me, g_cnsMdbFileame, g_cnsMdbSubFolder)
        ' ウィンドウ制御関連クラスの初期化
        g_objAboutWindow = New clsAboutWindow1(Me)
        ' ダブルクリック抑制クラスの初期化
        g_objOmitDoubleClick = New clsOmitDoubleClick2(Me)
        ' DataGridView制御関連クラスの初期化
        g_objAboutDGV = New clsAboutDataGridView1
        '-------------------------------------------------------------------------------------------
        ' DataGridView(登録一覧)のカラム設定
        Dim tblColInfo() As g_typDGVColInfo = Nothing
        With g_objAboutDGV
            Call .SetColumnInfo(tblColInfo, "社員CD", 50, g_cnsDG_MC)   ' (00)社員コード
            Call .SetColumnInfo(tblColInfo, "氏名", 100, , _
                                g_cnsSM_Programmatic)                   ' (01)氏名
            Call .SetColumnInfo(tblColInfo, "部署名", 150, , _
                                g_cnsSM_Programmatic)                   ' (02)部署名
            Call .SetColumnInfo(tblColInfo, "役職名", 100, , _
                                g_cnsSM_Programmatic)                   ' (03)役職名
            Call .SetColumnInfo(tblColInfo, "入社日", 90, g_cnsDG_MC)   ' (04)入社日
            Call .SetColumnInfo(tblColInfo, "退職日", 90, g_cnsDG_MC)   ' (05)退職日
            Call .SetColumnInfo(tblColInfo, "部署CD", 60, g_cnsDG_MC)   ' (06)部署コード(非表示)
            Call .SetColumnInfo(tblColInfo, "役職CD", 50, g_cnsDG_MC)   ' (07)役職コード(非表示)
            Call .SetColumnInfo(tblColInfo, "カナ氏名", 150)            ' (08)カナ氏名(非表示)
            Call .SetColumnInfo(tblColInfo, "開始日", 90, g_cnsDG_MC)   ' (09)配属開始日
            ' 初期カラム幅設定を退避
            g_tblDefaultColumnWidth = .GetDefaultColumnWidth(tblColInfo)
            ' 列幅を設定退避値で置き換える
            Call .AdjustColumnWidth(tblColInfo, My.Settings.ICHIRAN_COL_Width)
            '---------------------------------------------------------------------------------------
            ' DataGridViewの初期設定(一般一覧用)
            Call .InitDataGridView1(DGV_ICHIRAN, tblColInfo, 1)
            '---------------------------------------------------------------------------------------
            ' 半角英数列のフォントをMSゴシック10Pに変更
            Dim objFont10 As Font = New Font(g_cnsStdFontName, g_cnsFontSize975) ' 英数項目用
            ' DataGridViewのその他調整
            With DGV_ICHIRAN
                ' プログラムSORT列指定
                .Columns(1).Tag = 8                 ' 氏名⇒カナ氏名
                .Columns(2).Tag = 6                 ' 部署名⇒部署コード
                .Columns(3).Tag = 7                 ' 役職名⇒役職コード
                ' コード、日付列は当幅フォントに変更
                .Columns(0).DefaultCellStyle.Font = objFont10
                .Columns(4).DefaultCellStyle.Font = objFont10
                .Columns(5).DefaultCellStyle.Font = objFont10
                .Columns(6).DefaultCellStyle.Font = objFont10
                .Columns(7).DefaultCellStyle.Font = objFont10
                .Columns(9).DefaultCellStyle.Font = objFont10
                ' 部署コード以降は非表示
                .Columns(6).Visible = False
                .Columns(7).Visible = False
                .Columns(8).Visible = False
                .Columns(9).Visible = False
            End With
            '---------------------------------------------------------------------------------------
            ' 列配置を設定退避値で置き換える
            Call .AdjustDGVColumnDisplayIndex(DGV_ICHIRAN, My.Settings.ICHIRAN_DisplayIndex)
        End With
        '-------------------------------------------------------------------------------------------
        ' 一覧表示用抽出SQL文共通部の編集(WHERE句の前まで)
        g_strSQL_Base = "SELECT H.[SCD]"                                ' (00)社員コード
        g_strSQL_Base &= ",S.[KANJI_SEI]+S.[KANJI_MEI]"                 ' (01)氏名(漢字)
        g_strSQL_Base &= ",B.[BUSYO_NM]"                                ' (02)部署名
        g_strSQL_Base &= ",Y.[YAKU_NM]"                                 ' (03)役職名
        g_strSQL_Base &= ",S.[NYUSYA_YMD]"                              ' (04)入社日
        g_strSQL_Base &= ",S.[TAISYOKU_YMD]"                            ' (05)退職日
        g_strSQL_Base &= ",H.[BUSYO_CD]"                                ' (06)部署コード
        g_strSQL_Base &= ",H.[YAKU_CD]"                                 ' (07)役職コード
        g_strSQL_Base &= ",S.[KANA_SEI]+S.[KANA_MEI]"                   ' (08)氏名(カナ)
        g_strSQL_Base &= ",H.[KAISHI_YMD]"                              ' (09)配属開始日
        g_strSQL_Base &= " FROM (((" & g_cnsMST_HAIZOKU & " AS H"
        g_strSQL_Base &= g_cnsIN_JOIN & g_cnsMST_SYAIN & " AS S ON H.[SCD]=S.[SCD])"
        g_strSQL_Base &= g_cnsOUT_JOIN & g_cnsMST_BUSYO & " AS B ON H.[BUSYO_CD]=B.[BUSYO_CD])"
        g_strSQL_Base &= g_cnsOUT_JOIN & g_cnsMST_YAKU & " AS Y ON H.[YAKU_CD]=Y.[YAKU_CD])"
    End Sub

    '***********************************************************************************************
    ' ■■■ フォームイベント ■■■
    '***********************************************************************************************
    '* 処理名 :Form_FormClosed
    '* 機能  :フォーム消失(FormClosed)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月15日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub Form_FormClosed(ByVal sender As Object, _
                                ByVal e As FormClosedEventArgs) Handles Me.FormClosed
        '-------------------------------------------------------------------------------------------
        ' DataGridViewの列幅、列配置等を退避
        With My.Settings
            .ICHIRAN_COL_Width = g_objAboutDGV.GetDGVColumnWidth(DGV_ICHIRAN)
            .ICHIRAN_DisplayIndex = g_objAboutDGV.GetDGVColumnDisplayIndex(DGV_ICHIRAN)
            Call g_objAboutWindow.FormSaveSettings1(.ICHIRAN_FormLocation, _
                                                    .ICHIRAN_FormSize, _
                                                    .ICHIRAN_WindowState)
            ' 設定を保存
            .Save()
        End With
        '-------------------------------------------------------------------------------------------
        ' DataGridViewのColumnHeaderMouseClickイベントハンドラ解放(共通記述)
        RemoveHandler DGV_ICHIRAN.ColumnHeaderMouseClick, _
            AddressOf g_objAboutDGV.DGV_ColumnHeaderMouseClick
    End Sub

    '***********************************************************************************************
    '* 処理名 :Form_Load
    '* 機能  :フォーム初期化(Load)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月15日
    '* 作成者 :井上 治
    '* 更新日 :2018年05月07日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        '-------------------------------------------------------------------------------------------
        ' フォーム位置・サイズ制御
        With My.Settings
            Call g_objAboutWindow.FormAdjustLocationSize1(.ICHIRAN_FormLocation, _
                                                          .ICHIRAN_FormSize, Me.Size)
            Me.WindowState = .ICHIRAN_WindowState
        End With
        '-------------------------------------------------------------------------------------------
        ' DataGridViewのColumnHeaderMouseClickイベントハンドラ追加(共通記述)
        AddHandler DGV_ICHIRAN.ColumnHeaderMouseClick, _
            AddressOf g_objAboutDGV.DGV_ColumnHeaderMouseClick
    End Sub

    '***********************************************************************************************
    '* 処理名 :Form_Shown
    '* 機能  :フォーム初期表示(Shown)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月15日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub Form_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
        '-------------------------------------------------------------------------------------------
        ' 一覧再更新表示
        If Not FP_ListUpdate() Then
            Me.Close()
            Exit Sub
        End If
        '-------------------------------------------------------------------------------------------
        ' 初期表示動作完了
        g_objOmitDoubleClick.Shown = True
    End Sub

    '***********************************************************************************************
    ' ■■■ コントロールイベント ■■■
    '***********************************************************************************************
    '* 処理名 :DGV_ICHIRAN_KeyUp
    '* 機能  :グリッド表示のキーイベント(KeyUp)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub DGV_ICHIRAN_KeyUp(ByVal sender As Object, _
                                  ByVal e As System.Windows.Forms.KeyEventArgs) _
                                  Handles DGV_ICHIRAN.KeyUp
        '-------------------------------------------------------------------------------------------
        ' Ctrl+Cでコピーができないようにする。
        If (e.Control AndAlso (e.KeyCode = Keys.C)) Then
            ' クリップボードをクリア
            Clipboard.Clear()
        End If
    End Sub

    '***********************************************************************************************
    '* 処理名 :DGV_ICHIRAN_CellClick
    '* 機能  :グリッド表示のイベント(CellClick)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub DGV_ICHIRAN_CellClick(ByVal sender As Object, _
                                      ByVal e As DataGridViewCellEventArgs) _
                                      Handles DGV_ICHIRAN.CellClick
        '-------------------------------------------------------------------------------------------
        ' ダブルクリック等の多重操作を抑制
        If g_objOmitDoubleClick.CheckDoubleClick() Then Exit Sub
        '-------------------------------------------------------------------------------------------
        ' DataGridViewのセル選択
        Dim intRow As Integer = e.RowIndex                              ' 行INDEX
        ' 選択行0件時はスキップ
        If ((intRow < 0) OrElse (DGV_ICHIRAN.SelectedRows.Count = 0)) Then Exit Sub
        ' 処理中判定スイッチ対応
        g_objOmitDoubleClick.OmitDoubleClick = True
        '-------------------------------------------------------------------------------------------
        ' 詳細表示フォームを起動
        Call GP_ShowEntryForm(intRow)
    End Sub

    '***********************************************************************************************
    '* 処理名 :DGV_ICHIRAN_KeyDown
    '* 機能  :グリッド表示のイベント(KeyDown)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub DGV_ICHIRAN_KeyDown(ByVal sender As Object, _
                                    ByVal e As System.Windows.Forms.KeyEventArgs) _
                                    Handles DGV_ICHIRAN.KeyDown
        '-------------------------------------------------------------------------------------------
        ' ダブルクリック等の多重操作を抑制
        If g_objOmitDoubleClick.CheckDoubleClick() Then Exit Sub
        '-------------------------------------------------------------------------------------------
        ' Enterキーでなければ処理なし
        If ((e.KeyCode <> Keys.Enter) OrElse e.Shift) Then Exit Sub
        ' 表示0件時はスキップ
        If DGV_ICHIRAN.SelectedCells.Count = 0 Then Exit Sub
        e.Handled = True                                ' Enterキーで下行に移動させない
        Dim intRow As Integer = DGV_ICHIRAN.SelectedCells.Item(0).RowIndex ' 行INDEX
        ' 行未選択でなければ処理なし
        If intRow < 0 Then Exit Sub
        ' 処理中判定スイッチ対応
        g_objOmitDoubleClick.OmitDoubleClick = True
        '-------------------------------------------------------------------------------------------
        ' 詳細表示フォームを起動
        Call GP_ShowEntryForm(intRow)
    End Sub

    '***********************************************************************************************
    '* 処理名 :DGV_ICHIRAN_Leave
    '* 機能  :グリッド表示のフォーカスアウトイベント(Leave)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub DGV_ICHIRAN_Leave(ByVal sender As Object, _
                                  ByVal e As System.EventArgs) Handles DGV_ICHIRAN.Leave
        '-------------------------------------------------------------------------------------------
        DGV_ICHIRAN.CurrentCell = Nothing
    End Sub

    '***********************************************************************************************
    '   ■■■ サブ処理 ■■■
    '***********************************************************************************************
    '* 処理名 :FP_ListUpdate
    '* 機能  :一覧再更新表示
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :処理成否(Boolean)
    '* 引数  :(なし)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月15日
    '* 作成者 :井上 治
    '* 更新日 :2018年05月07日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Function FP_ListUpdate() As Boolean
        '-------------------------------------------------------------------------------------------
        ' 配属情報の抽出
        Dim dbTbl As DataTable = Nothing                            ' DataTable
        Dim strToday As String = FP_SQLDateSUB2(Today)              ' 本日日付(編集)
        Dim strSQL As String = g_strSQL_Base                        ' SQL文
        strSQL &= " WHERE S.[NYUSYA_YMD]<=" & strToday
        strSQL &= " AND (S.[TAISYOKU_YMD] IS NULL OR S.[TAISYOKU_YMD]>" & strToday & g_cnsKO
        strSQL &= " ORDER BY H.[BUSYO_CD],H.[YAKU_CD],H.[SCD];"
        ' DataTable取得
        If Not g_objAboutMDB.GetDataTableOle(dbTbl, strSQL, g_cnsMST_HAIZOKU) Then Return False
        '-------------------------------------------------------------------------------------------
        Dim intIx As Integer = 0                                    ' テーブルINDEX
        With DGV_ICHIRAN
            ' スクロールバーを一旦、非表示にする
            .ScrollBars = ScrollBars.None
            ' DataGridViewを一旦、非表示にする
            .Visible = False
            ' SORTマークを部署の昇順に設定
            .Columns(2).HeaderCell.SortGlyphDirection = g_cnsSO_Ascending
            ' 他のプログラムソート列のSortマーク解除
            .Columns(1).HeaderCell.SortGlyphDirection = g_cnsSO_None
            .Columns(3).HeaderCell.SortGlyphDirection = g_cnsSO_None
            ' 前回の一覧をクリア
            If .Rows.Count <> 0 Then .Rows.Clear()
            ' DataTableの全件を繰り返す
            Do While intIx < dbTbl.Rows.Count
                ' 行を追加
                .Rows.Add()
                ' 一覧再更新表示サブ(1行単位)
                Call GP_ListUpdateSub(intIx, dbTbl.Rows(intIx).ItemArray.Clone)
                ' 次へ
                intIx += 1
            Loop
            ' DataGridViewを再表示にする
            .Visible = True
            ' スクロールバーを再表示する
            .ScrollBars = ScrollBars.Both
        End With
        ' データテーブルをクリア
        dbTbl.Clear()
        dbTbl.Reset()
        Return True
    End Function

    '***********************************************************************************************
    '* 処理名 :GP_ShowEntryForm
    '* 機能  :入力(参照)用フォーム表示
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = DataGridViewの行Index(Integer)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:更新登録フォームを表示させる
    '* 注意事項:本サンプルでは新規登録の対応は行なわない
    '***********************************************************************************************
    Private Sub GP_ShowEntryForm(ByVal intRow As Integer)
        '-------------------------------------------------------------------------------------------
        Dim strScd As String = DGV_ICHIRAN.Rows(intRow).Cells(0).Value ' 社員コード
        Dim dteKaishiYmd As Date = Date.Parse(DGV_ICHIRAN.Rows(intRow).Cells(9).Value) ' 配属開始日
        '-------------------------------------------------------------------------------------------
        ' 詳細登録フォームを起動
        If g_objSYOUSAI_Form Is Nothing Then
            g_objSYOUSAI_Form = New dlgGetMdbDataTest02(g_objAboutMDB, g_strSQL_Base)
        End If
        With g_objSYOUSAI_Form
            .prpScd = strScd
            .prpKaishiYmd = dteKaishiYmd
            ' 詳細画面を起動(モーダル)
            .ShowDialog(Me)
            ' 処理中判定スイッチ対応
            g_objOmitDoubleClick.OmitDoubleClick = True
            ' 更新が成功した場合、一覧再表示
            If .prpUpdateResult <> 0 Then
                Call GP_ListUpdate2(intRow, strScd, dteKaishiYmd)
            End If
        End With
    End Sub

    '***********************************************************************************************
    '* 処理名 :GP_ListUpdate2
    '* 機能  :一覧再更新表示(1行単位)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = 更新行Index(Integer)         ※新規登録時は-1
    '*      Arg2 = 社員コード(String)
    '*      Arg3 = 配属開始日(Date)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub GP_ListUpdate2(ByVal intRow As Integer, _
                               ByVal strScd As String, _
                               ByVal dteKaishiYmd As Date)
        '-------------------------------------------------------------------------------------------
        ' 配属の読み込み
        Dim dbTbl As DataTable = Nothing                            ' DataTable
        Dim strSQL As String = g_strSQL_Base                        ' SQL文
        strSQL &= " WHERE H.[SCD]='" & strScd & g_cnsSC
        strSQL &= " AND H.[KAISHI_YMD]=" & FP_SQLDateSUB2(dteKaishiYmd) & g_cnsCOL
        ' DataTable取得
        If Not g_objAboutMDB.GetDataTableOle(dbTbl, strSQL, g_cnsMST_HAIZOKU) Then
            Me.Close()
            Exit Sub
        End If
        '-------------------------------------------------------------------------------------------
        ' 追加モード時はDataGridViewに行を追加
        If intRow < 0 Then
            With DGV_ICHIRAN
                intRow = .Rows.Count
                .Rows.Add()
            End With
        End If
        '-------------------------------------------------------------------------------------------
        ' 一覧再更新表示サブ(1行単位)
        Call GP_ListUpdateSub(intRow, dbTbl.Rows(0).ItemArray.Clone)
        ' データテーブルをクリア
        dbTbl.Clear()
        dbTbl.Reset()
    End Sub

    '***********************************************************************************************
    '* 処理名 :GP_ListUpdateSub
    '* 機能  :一覧再更新表示サブ(1行単位)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = 行INDEX(Integer)
    '*      Arg2 = dbTbl.Rows(IX).ItemArray(Object)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:FP_ListUpdateとGP_ListUpdate2から呼び出される
    '***********************************************************************************************
    Private Sub GP_ListUpdateSub(ByRef intRow As Integer, _
                                 ByRef objItemArray As Object())
        '-------------------------------------------------------------------------------------------
        With DGV_ICHIRAN.Rows(intRow)
            .Cells(0).Value = objItemArray(0)                   ' (00)社員コード
            .Cells(1).Value = objItemArray(1)                   ' (01)氏名(漢字)
            ' 氏名(漢字)のToolTipに氏名(カナ)を設定
            .Cells(1).ToolTipText = objItemArray(8)
            .Cells(2).Value = objItemArray(2)                   ' (02)部署名
            .Cells(3).Value = objItemArray(3)                   ' (03)役職名
            .Cells(4).Value = FP_EditDate(objItemArray(4))      ' (04)入社日
            .Cells(5).Value = FP_EditDate(objItemArray(5))      ' (05)退職日
            .Cells(6).Value = objItemArray(6)                   ' (06)部署コード
            .Cells(7).Value = objItemArray(7)                   ' (07)役職コード
            .Cells(8).Value = objItemArray(8)                   ' (08)氏名(カナ)
            .Cells(9).Value = FP_EditDate(objItemArray(9))      ' (09)配属開始日
            ' 退職者か(退職日有り)
            If .Cells(5).Value.ToString.Length <> 0 Then
                ' 退職者はグレーで塗りつぶし
                For intCol As Integer = 0 To g_cnsDGVColumnMAX
                    .Cells(intCol).Style.BackColor = g_colorRetire
                Next intCol
            End If
        End With
    End Sub

    '----------------------------------------<< End of Source >>------------------------------------
End Class
前ページの一覧画面と一覧表示上の機能は同じですが、「行」を選択して「配属情報の登録・変更」画面を表示させるところと、その画面で登録が行なわれた時にその行だけ一覧を更新させる仕組みを盛り込んでいます。 「行の選択」に関してはDataGridViewのコントロールイベントを追加しており、これでマウスのクリックと↑↓キーで行を移動させてEnterキーで決定させる方法についても 同様に「配属情報の登録・変更」画面を表示させるためのプロシージャ「GP_ShowEntryForm」を呼び出すように対応させています。
また、共通クラスの追加がありますが、これは後ろで説明します。

一覧表示の「FP_ListUpdate」は表示機能は変わらないのですが、「配属情報の登録・変更」画面の登録後にDataGridViewの一覧の対象行のみを更新する記述があり、 DataGridViewの行内の各セルに関する更新部分だけを「GP_ListUpdateSub」として抜き出しました。 これは「配属情報の登録・変更」画面の登録後の「一覧再更新表示(1行単位:GP_ListUpdate2)」からも呼び出されます。
「配属情報の登録・変更」画面を表示させるためのプロシージャ「GP_ShowEntryForm」では画面「dlgGetMdbDataTest02」を社員コードと配属開始日をプロパティで引き渡して表示します。 その後に処理結果がゼロでなければ「一覧再更新表示(1行単位:GP_ListUpdate2)」を呼び出してその行を更新します。

次は「配属情報の登録・変更」画面のソースコードです。
このページの先頭の画像の中央にポップアップしている「登録」ボタンがある小さいフォームのソースコードです。

'***************************************************************************************************
'   配属一覧サンプル②(更新登録画面)                           dlgGetMdbDataTest02(Form)
'
'   作成者:井上治  URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
' 変更日付 Rev     変更履歴内容-------------------------------------------------------------------->
' 17/01/22(1.0.1.0)新規作成
' 17/01/29(1.0.2.0)ダブルクリック抑制、未更新終了チェック関連の共通クラス化対応
'***************************************************************************************************
Friend Class dlgGetMdbDataTest02
    '===============================================================================================
    Private Const g_cnsTitle As String = "配属一覧サンプル②"
    '-----------------------------------------------------------------------------------------------
    Private g_objAboutMDB As clsAboutMDB2                   ' データベースI/Oクラス(MDB用)
    Private g_objCheckNotUpdate As clsCheckNotUpdate2       ' 未更新終了チェック関連クラス
    Private g_objOmitDoubleClick As clsOmitDoubleClick2     ' ダブルクリック抑制クラス
    '-----------------------------------------------------------------------------------------------
    ' 一覧フォームとの受け渡し項目
    Private g_strSQL_Base As String                         ' 抽出SQL文共通部
    Private g_strScd As String                              ' 社員コード
    Private g_dteKaishiYmd As Date                          ' 配属開始日
    ' 処理モードは今回のサンプルは「2=変更」のみ
    Private g_intUpdateMode As Integer = 2                  ' 処理モード(0=参照,1=新規,2=変更)
    Private g_intUpdateResult As Integer = 0                ' 更新結果(0=無,1=追加,2=更新,9=削除)
    '-----------------------------------------------------------------------------------------------
    ' コンボボックスに対応したコードテーブル
    Private g_tblBusyoCd() As String                        ' 部署コードテーブル
    Private g_tblYakuCd() As String                         ' 役職コードテーブル

    '***********************************************************************************************
    ' ■■■ 初期化 ■■■
    '***********************************************************************************************
    '* 処理名 :New
    '* 機能  :初期化
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = データベースI/Oクラス(Object)
    '*      Arg2 = 抽出SQL文共通部(String)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Friend Sub New(ByRef objAboutMDB As clsAboutMDB2, ByVal strSQL_Base As String)
        '-------------------------------------------------------------------------------------------
        ' ※Windowsフォームデザイナ初期化(必須)
        Call InitializeComponent()
        ' フォームデザイナモード時は以下をスキップする
        If Me.DesignMode Then Exit Sub
        '-------------------------------------------------------------------------------------------
        g_objAboutMDB = objAboutMDB                         ' データベースI/Oクラス(MDB用)
        g_strSQL_Base = strSQL_Base                         ' 抽出SQL文共通部
        '-------------------------------------------------------------------------------------------
        ' 未更新終了チェック関連クラスの初期化
        g_objCheckNotUpdate = New clsCheckNotUpdate2(Me)
    End Sub

    '***********************************************************************************************
    ' ■■■ フォームイベント ■■■
    '***********************************************************************************************
    '* 処理名 :Form_Load
    '* 機能  :フォームイベント(Load)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        '-------------------------------------------------------------------------------------------
        ' 一旦、登録ボタン等を消去
        BTN_OK.Enabled = False
        '-------------------------------------------------------------------------------------------
        ' ダブルクリック抑制クラスの初期化
        g_objOmitDoubleClick = New clsOmitDoubleClick2(Me)
    End Sub

    '***********************************************************************************************
    '* 処理名 :Form_Shown
    '* 機能  :フォーム初期表示(Shown)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub Form_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
        '-------------------------------------------------------------------------------------------
        g_intUpdateResult = 0
        '-------------------------------------------------------------------------------------------
        ' フォーム位置の保持
        If Me.StartPosition <> FormStartPosition.Manual Then
            Me.StartPosition = FormStartPosition.Manual
        End If
        '-------------------------------------------------------------------------------------------
        ' 初回起動時は初期セットアップを行なう
        If g_objOmitDoubleClick.FirstShown Then
            ' コンボリスト等の初期セットアップ
            If Not FP_SetFormList() Then
                g_objCheckNotUpdate.FatalError = True
                Me.Close()
                Exit Sub
            End If
            g_objOmitDoubleClick.FirstShown = False
        End If
        '-------------------------------------------------------------------------------------------
        ' 指定社員情報の表示
        If Not FP_ShowSyainInfo() Then
            g_objCheckNotUpdate.FatalError = True
            Me.Close()
            Exit Sub
        End If
        '-------------------------------------------------------------------------------------------
        ' 未登録終了警告スイッチをクリア
        g_objCheckNotUpdate.NotUpdate = False
        g_objOmitDoubleClick.Shown = True
    End Sub

    '***********************************************************************************************
    ' ■■■ コントロールイベント ■■■
    '***********************************************************************************************
    '* 処理名 :BTN_CANCEL_Click
    '* 機能  :「キャンセル」ボタンイベント(Click)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub BTN_CANCEL_Click(ByVal sender As Object, _
                                 ByVal e As System.EventArgs) Handles BTN_CANCEL.Click
        '-------------------------------------------------------------------------------------------
        ' ダブルクリック等の多重操作を抑制
        If g_objOmitDoubleClick.CheckDoubleClick(True) Then Exit Sub
        '-------------------------------------------------------------------------------------------
        ' フォームを閉じる
        Me.Close()
    End Sub

    '***********************************************************************************************
    '* 処理名 :BTN_OK_Click
    '* 機能  :「登録」ボタンイベント(Click)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub BTN_OK_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles BTN_OK.Click
        '-------------------------------------------------------------------------------------------
        ' ダブルクリック等の多重操作を抑制
        If g_objOmitDoubleClick.CheckDoubleClick() Then Exit Sub
        '-------------------------------------------------------------------------------------------
        Me.Activate()
        BTN_OK.Focus()
        ' 「登録」ボタン処理
        Call GP_OK_Click()
    End Sub

    '***********************************************************************************************
    '* 処理名 :CBO_BUSYO_SelectedIndexChanged
    '* 機能  :「部署」コンボイベント(SelectedIndexChanged)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub CBO_BUSYO_SelectedIndexChanged(ByVal sender As Object, _
                                               ByVal e As System.EventArgs) _
                                               Handles CBO_BUSYO.SelectedIndexChanged
        '-------------------------------------------------------------------------------------------
        ' ダブルクリック等の多重操作を抑制
        If g_objOmitDoubleClick.CheckDoubleClick() Then Exit Sub
        '-------------------------------------------------------------------------------------------
        ' 未登録終了警告スイッチをセット
        g_objCheckNotUpdate.NotUpdate = True
        BTN_OK.Enabled = True
    End Sub

    '***********************************************************************************************
    '* 処理名 :CBO_YAKU_SelectedIndexChanged
    '* 機能  :「役職」コンボイベント(SelectedIndexChanged)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub CBO_YAKU_SelectedIndexChanged(ByVal sender As Object, _
                                              ByVal e As System.EventArgs) _
                                              Handles CBO_YAKU.SelectedIndexChanged
        '-------------------------------------------------------------------------------------------
        ' ダブルクリック等の多重操作を抑制
        If g_objOmitDoubleClick.CheckDoubleClick() Then Exit Sub
        '-------------------------------------------------------------------------------------------
        ' 未登録終了警告スイッチをセット
        g_objCheckNotUpdate.NotUpdate = True
        BTN_OK.Enabled = True
    End Sub

    '***********************************************************************************************
    ' ■■■ サブ処理(登録更新系) ■■■
    '***********************************************************************************************
    '* 処理名 :GP_OK_Click
    '* 機能  :「登録」ボタン処理
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(なし)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub GP_OK_Click()
        '-------------------------------------------------------------------------------------------
        If Not g_objCheckNotUpdate.NotUpdate Then
            MessageBox.Show(Me, _
                            "何も変更されていません。", _
                            g_cnsTitle, _
                            MessageBoxButtons.OK, _
                            MessageBoxIcon.Information)
            Exit Sub
        ElseIf Not FP_CheckForm() Then          ' 登録チェック
            Exit Sub
        End If
        '-------------------------------------------------------------------------------------------
        ' 登録確認メッセージ
        If MessageBox.Show( _
            Me, _
            "表示されている内容を登録します。" & _
            ControlChars.CrLf & ControlChars.CrLf & "よろしいですね?", _
            g_cnsTitle, _
            MessageBoxButtons.YesNo, _
            MessageBoxIcon.Information) <> DialogResult.Yes Then Exit Sub
        ' 処理中判定スイッチ対応
        g_objOmitDoubleClick.OmitDoubleClick = True
        '-------------------------------------------------------------------------------------------
        ' 登録(更新)処理
        If FP_UpdateTables() Then
            ' 処理結果を返す⇒今回のサンプルは「2=変更」のみ
            g_intUpdateResult = g_intUpdateMode
            ' 未登録終了警告スイッチをクリア
            g_objCheckNotUpdate.NotUpdate = False
            Me.Close()
        End If
    End Sub

    '***********************************************************************************************
    '* 処理名 :FP_CheckForm
    '* 機能  :登録チェック
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :チェック成否(Boolean)
    '* 引数  :(なし)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Function FP_CheckForm() As Boolean
        '-------------------------------------------------------------------------------------------
        Dim strMSG As String = String.Empty                     ' エラーメッセージ
        ' 部署未選択
        If CBO_BUSYO.SelectedIndex < 0 Then
            Call GP_AppendMessage(strMSG, "「部署」が選択されていません。")
        End If
        ' 役職未選択
        If CBO_YAKU.SelectedIndex < 0 Then
            Call GP_AppendMessage(strMSG, "「役職」が選択されていません。")
        End If
        '-------------------------------------------------------------------------------------------
        ' チェック結果
        If strMSG.Length <> 0 Then
            MessageBox.Show(Me, _
                            strMSG, _
                            g_cnsTitle, _
                            MessageBoxButtons.OK, _
                            MessageBoxIcon.Exclamation)
            Return False
        Else
            Return True
        End If
    End Function

    '***********************************************************************************************
    '* 処理名 :FP_UpdateTables
    '* 機能  :登録(更新)処理
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :処理成否(Boolean)
    '* 引数  :(なし)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:本処理は単一テーブル、単一レコードのみの更新用として調整(非Transactionモード)
    '* 注意事項:
    '***********************************************************************************************
    Private Function FP_UpdateTables() As Boolean
        '-------------------------------------------------------------------------------------------
        Dim blnResult As Boolean = False                            ' 処理結果
        Dim blnSuccess As Boolean = False                           ' 登録成否
        Dim strMsgHeader As String = String.Empty                   ' メッセージヘッダ
        Dim strMSG As String = String.Empty                         ' メッセージ
        Dim strSQL As String = String.Empty                         ' SQL文
        Dim blnUpdate As Boolean = False                            ' 更新有りフラグ
        Dim tblFldO() As Object = Nothing                           ' レコードフィールド
        ' MDB接続
        Using dbCon As OleDb.OleDbConnection = g_objAboutMDB.GetConnection(blnResult)
            ' 接続失敗
            If Not blnResult Then Return False
            '---------------------------------------------------------------------------------------
            ' データベースに接続
            dbCon.Open()
            ' コマンド割り当て
            Using dbCommand As OleDb.OleDbCommand = dbCon.CreateCommand()
                Try
                    strMsgHeader = g_cnsMDBMSG003                       ' 参照失敗
                    Dim strWhere As String = " WHERE [SCD]='" & g_strScd & g_cnsSC ' WHERE句
                    strWhere &= " AND [KAISHI_YMD]=" & FP_SQLDateSUB2(g_dteKaishiYmd) & g_cnsCOL
                    strSQL = g_cnsSELECT_AST & g_cnsMST_HAIZOKU & strWhere
                    ' DataTableにレコードを読み込む
                    Dim dbTbl As DataTable = FP_GetDataTable(dbCommand, strSQL) ' DataTable
                    ' 読込レコードがあるか
                    If dbTbl.Rows.Count <> 0 Then
                        ' 更新可
                        blnUpdate = True
                        ' 最終的な変更前レコード内容の取得
                        tblFldO = dbTbl.Rows(0).ItemArray.Clone
                        ' NULLがあり得る日付項目はNothingに変換
                        Call GP_ReplaceDateFields(tblFldO, New Integer() {1, 2})
                    Else
                        ' 未登録(今回のサンプルは「2=変更」のみ)
                        strMSG = g_cnsMDBMSG012
                    End If
                    ' データテーブルをクリア
                    dbTbl.Clear()
                    dbTbl.Reset()
                    ' 更新可か
                    If blnUpdate Then
                        ' 更新有無判定のためクリア
                        strSQL = String.Empty
                        ' 更新SQL文の編集
                        Call GP_MakeUpdateSql(tblFldO, strWhere, strSQL)
                        ' 更新対象があるか
                        If strSQL.Length <> 0 Then
                            strMsgHeader = g_cnsMDBMSG002
                            ' コマンド発行
                            dbCommand.CommandText = strSQL
                            dbCommand.ExecuteNonQuery()
                            blnSuccess = True
                        Else
                            ' 更新項目無し
                            strMSG = "更新対象項目がありませんでした。"
                        End If
                    End If
                Catch ex As Exception
                    ' 更新SQLエラー処理(致命エラー扱い)
                    Call g_objAboutMDB.ExecuteSQLError(ex.Message, _
                                                       strMsgHeader, _
                                                       g_cnsMST_HAIZOKU, _
                                                       strSQL)
                End Try
            End Using
            ' データベースを切断
            dbCon.Close()
            '---------------------------------------------------------------------------------------
        End Using
        '-------------------------------------------------------------------------------------------
        ' エラーがあるか
        If strMSG.Length <> 0 Then
            ' ここでのエラーには致命エラーは含まれない
            MessageBox.Show(Me, _
                            strMSG, _
                            g_cnsTitle, _
                            MessageBoxButtons.OK, _
                            MessageBoxIcon.Exclamation)
        End If
        Return blnSuccess
    End Function

    '***********************************************************************************************
    '* 処理名 :GP_MakeUpdateSql
    '* 機能  :更新登録SQL文編集
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = 現行テーブル内容(Array:Object)
    '*           Arg2 = WHERE句(String)
    '*      Arg3 = 更新SQL文(String)               ※Ref参照
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:本処理(サンプル)では1社員コードに対して1配属情報として更新する
    '***********************************************************************************************
    Private Sub GP_MakeUpdateSql(ByVal tblFldO() As Object, _
                                 ByVal strWhere As String, _
                                 ByRef strUpdSQL As String)
        '-------------------------------------------------------------------------------------------
        ' フォーム上のアイテムから更新用テーブルを作成
        Dim tblFldN() As Object = FP_SetTableFromItems()            ' 新規登録側テーブル
        '-------------------------------------------------------------------------------------------
        ' UPDATE文を編集
        Dim strSQL As String = g_cnsUPDATE & g_cnsMST_HAIZOKU & g_cnsSET ' SQL文
        Dim intIx As Integer = 2                                    ' 更新開始フィールドINDEX
        Dim intCntUpd As Integer = 0                                ' 更新項目件数
        ' キー項目以後を繰り返す
        Do While intIx <= g_tblFld_MST_HAIZOKU.GetUpperBound(0)
            ' 変更がある項目のみSQLに追加
            If tblFldN(intIx) <> tblFldO(intIx) Then
                intCntUpd += 1
                ' 後続が" SET "でなければカンマを付加
                If Not strSQL.EndsWith(g_cnsSET) Then
                    strSQL &= g_cnsCOM
                End If
                ' 値が変更されたフィールドのみ更新
                strSQL &= g_tblFld_MST_HAIZOKU(intIx) & g_cnsEQ
                ' データタイプ判定(今回は日付と文字列のみ)
                Select Case g_tblFldTyp_MST_HAIZOKU(intIx)
                    Case 5                                          ' 日付
                        strSQL &= FP_SQLDateSUB2(tblFldN(intIx))
                    Case Else                                       ' 文字列
                        strSQL &= g_cnsSC & tblFldN(intIx).ToString & g_cnsSC
                End Select
            End If
            ' 次のフィールドへ
            intIx += 1
        Loop
        ' 更新項目があったか
        If intCntUpd <> 0 Then
            ' WHERE句を接続
            strUpdSQL = strSQL & strWhere
        End If
    End Sub

    '***********************************************************************************************
    '* 処理名 :FP_SetTableFromItems
    '* 機能  :フォーム上のアイテムから更新用テーブルを作成(配属マスタ)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :テーブル(Array:Object)
    '* 引数  :(なし)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Function FP_SetTableFromItems() As Object()
        '-------------------------------------------------------------------------------------------
        Dim tblFldN() As Object                                         ' 新規登録側テーブル
        ReDim tblFldN(g_tblFld_MST_HAIZOKU.GetUpperBound(0))
        ' 社員コード以降のフィールドをセット
        tblFldN(0) = g_strScd                                           ' (00)社員コード
        tblFldN(1) = Date.Parse(LBL_KAISHI_YMD.Text)                    ' (01)開始日
        tblFldN(2) = g_cnsNullDate                                      ' (02)終了日(NULL)
        tblFldN(3) = g_tblBusyoCd(CBO_BUSYO.SelectedIndex)              ' (03)部署コード
        tblFldN(4) = g_tblYakuCd(CBO_YAKU.SelectedIndex)                ' (04)役職コード
        Return tblFldN
    End Function

    '***********************************************************************************************
    ' ■■■ サブ処理(表示系) ■■■
    '***********************************************************************************************
    '* 処理名 :FP_ShowSyainInfo
    '* 機能  :指定社員情報の表示
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :処理成否(Boolean)
    '* 引数  :(なし)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Function FP_ShowSyainInfo() As Boolean
        '-------------------------------------------------------------------------------------------
        Dim dbTbl As DataTable = Nothing                        ' DataTable
        Dim strSQL As String = g_strSQL_Base                    ' SQL文
        strSQL &= " WHERE H.[SCD]='" & g_strScd & g_cnsSC
        strSQL &= " AND H.[KAISHI_YMD]=" & FP_SQLDateSUB2(g_dteKaishiYmd) & g_cnsCOL
        ' DataTable取得
        If Not g_objAboutMDB.GetDataTableOle(dbTbl, strSQL, g_cnsMST_HAIZOKU) Then Return False
        ' 各コントロールに値をセット
        LBL_SCD.Text = dbTbl.Rows(0)(0)                         ' 社員コード
        LBL_SNAME.Text = dbTbl.Rows(0)(1)                       ' 氏名
        ToolTip1.SetToolTip(LBL_SNAME, dbTbl.Rows(0)(8))        ' カナ氏名(ToolTip)
        LBL_NYUSYA_YMD.Text = FP_EditDate(dbTbl.Rows(0)(4))     ' 入社日
        LBL_TAISYOKU_YMD.Text = FP_EditDate(dbTbl.Rows(0)(5))   ' 退職日
        ' 退職日(及び見出し)は登録されている場合のみ表示(NULL時は非表示)
        Dim blnTaisyoku As Boolean = Not DBNull.Value.Equals(dbTbl.Rows(0)(5)) ' 退職判定
        LBL_TAISYOKU_YMD.Visible = blnTaisyoku
        LBL_TAISYOKU_YMD2.Visible = blnTaisyoku
        LBL_KAISHI_YMD.Text = FP_EditDate(dbTbl.Rows(0)(9))     ' 配属開始日
        ' コンボボックスの選択をコードテーブルで行なう
        Call GP_SetComboIndexByCode(CBO_BUSYO, dbTbl.Rows(0)(6), g_tblBusyoCd) ' 部署
        Call GP_SetComboIndexByCode(CBO_YAKU, dbTbl.Rows(0)(7), g_tblYakuCd) ' 役職
        Return True
    End Function

    '***********************************************************************************************
    '* 処理名 :FP_SetFormList
    '* 機能  :コンボリスト等の初期セットアップ
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :処理成否(Boolean)
    '* 引数  :(なし)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Function FP_SetFormList() As Boolean
        '-------------------------------------------------------------------------------------------
        ' 部署コンボリストの生成
        Dim dbTbl As DataTable = Nothing                        ' DataTable
        Dim strSQL As String = "SELECT [BUSYO_CD]"              ' (00)部署コード
        strSQL &= ",[BUSYO_NM]"                                 ' (01)部署名
        strSQL &= g_cnsFROM & g_cnsMST_BUSYO
        strSQL &= " ORDER BY [BUSYO_CD];"
        ' DataTable取得
        If Not g_objAboutMDB.GetDataTableOle(dbTbl, strSQL, g_cnsMST_BUSYO) Then Return False
        ' コンボボックスのリストセット
        Call GP_SetComboBoxList(CBO_BUSYO, dbTbl, g_tblBusyoCd)
        '-------------------------------------------------------------------------------------------
        ' 役職コンボリストの生成
        strSQL = "SELECT [YAKU_CD]"                             ' (00)役職コード
        strSQL &= ",[YAKU_NM]"                                  ' (01)役職名
        strSQL &= g_cnsFROM & g_cnsMST_YAKU
        strSQL &= " ORDER BY [YAKU_CD];"
        ' DataTable取得
        If Not g_objAboutMDB.GetDataTableOle(dbTbl, strSQL, g_cnsMST_YAKU) Then Return False
        ' コンボボックスのリストセット
        Call GP_SetComboBoxList(CBO_YAKU, dbTbl, g_tblYakuCd)
        dbTbl.Clear()
        dbTbl.Reset()
        Return True
    End Function

    '***********************************************************************************************
    '   プロパティ
    '***********************************************************************************************
    ' 社員コード(String)
    '-----------------------------------------------------------------------------------------------
    Friend WriteOnly Property prpScd As String
        Set(value As String)
            g_strScd = value
        End Set
    End Property

    '===============================================================================================
    ' 配属開始日(Date)
    '-----------------------------------------------------------------------------------------------
    Friend WriteOnly Property prpKaishiYmd As Date
        Set(value As Date)
            g_dteKaishiYmd = value
        End Set
    End Property

    '===============================================================================================
    ' 更新結果(0=無,1=追加,2=更新,9=削除)(integer)
    '-----------------------------------------------------------------------------------------------
    Friend ReadOnly Property prpUpdateResult As Integer
        Get
            Return g_intUpdateResult
        End Get
    End Property

    '----------------------------------------<< End of Source >>------------------------------------
End Class
この画面はこのページで初めて登場したものです。 ひとつの社員コード、配属開始日が一覧で選択された時に呼び出されるものです。
社員コード、配属開始日はプロパティで渡されてから画面が呼び出されるようになっており、初回の呼び出し時には部署と配属のコンボのリストも生成されます。
フォーム初期表示(Form_Shown)イベントで「指定社員情報の表示(FP_ShowSyainInfo)」が呼び出され、該当の配属情報の内容が画面に表示されます。
今回はサンプルコードとして複雑にさせたくなかったため、配属情報の追加、削除は行なわずに部署と役職の変更のみの機能としています。 それでも600行強にはなってしまいました。これでも共通クラスを追加して本体ロジックに記述を集中できるようにしたつもりです。

特に「登録」ボタンをクリックしてからの処理については自分の中である程度標準化できたものを公開しています。
「登録」ボタンをクリックした後で呼び出される「登録ボタン処理(GP_OK_Click)」では入力チェック、登録確認の後に「登録(更新)処理(FP_UpdateTables)」が呼び出されます。 この中でデータベースコネクション、コマンドを取得して更新を行ないます。 今回は単一レコードのみの更新ですが、直前にレコードを参照し直しており、フィールドごとに比較して変更があるフィールドのみをSQLUPDATE文に編集する方法になっています。 この編集は「GP_MakeUpdateSql」プロシージャで行なっていますが、画面入力値を配置したテーブルと処理直前に読み出したテーブルをINDEXでフィールドを巡回して差異があるフィールドだけを UPDATE文のSET句に編集します。
画面入力値をテーブルに配置する「FP_SetTableFromItems」プロシージャの方はフィールドの数に影響されますが、 「GP_MakeUpdateSql」プロシージャの方はフィールドのデータタイプの数で多少変わるだけでフィールドの数の影響は受けません。
この方法は転用性が高い方法だと思うので、数多く手掛ける方にはお勧めです。
読み出してから、更新するまでを1つのコネクション接続の中で行なうのはMDBではあまり関係ありませんが、 SQLServerではレコードロックを行なって排他制御ができるので重要な方法です。
現在はMDBであってもこのような記述を行なっておくと、将来にSQLServer等に移行を行なうようなことがあれば移行作業が軽減されると思います。

また、例外発生時の対応もこの中に網羅されており、更新処理の中の作業ステップ、例外発生のテーブル、例外発生のSQL文がエラーメッセージに表示されるようになっています。

以降は「共通モジュール」「共通クラス」ですが、追加・変更があったものだけ提示します。
変更があった「共通モジュール」「共通クラス」はID(末尾の数字)を変更しています。 前ページにもあるもので、末尾が「2」のものは新たに追加されたか、変更がありますので先に概要を説明します。

種別 名称 内容
モジュール 共通モジュール
(modCommonModule2)
前ページでmodCommonModule1として説明しましたが、 これに登録画面で使う以下の機能プロシージャを追加しています。
・登録前のエラーチェックで複数のエラーがあった時でもメッセージを累積される処理
・更新登録時の新旧比較を用意にするために、日付のNULL値を最小値に置き換える処理
・コンボボックスのリストに登録する名称と対応するコードを正対させるための処理
テーブル情報定数モジュール
(modSampleCorp1MDB)
これは全システムで共通に利用できるモジュールということではなく、今回のデータベースを使用するプロジェクト内で共通して利用するデータベース名、テーブル名、及びテーブル内のフィールドをテーブル化したものを収容したモジュールです。
クラス データベースI/Oクラス
(clsAboutMDB2)
前ページでclsAboutMDB1として説明しましたが、 更新系に必要なメッセージやSQL文の編集に必要な定数の追加や、 更新系で使用するプロシージャ群を追加しています。
入力コントロールのダブルクリック抑制クラス
(clsOmitDoubleClick2)
.NET Frameworkの「ボタン」に記述上ではDoubleClickイベントがあるのですが、実際には動作することはなく、 操作上でダブルクリックしてしまうと、普通のClickイベントが複数回走ってしまうという問題があります。
これはClickイベントに先頭でEnabledを制御したり、スイッチをセットしたりしても後のイベントがバッファリングされるため回避はできず、 Application.Idleを待ってスイッチ解除するという方法を採る必要があります。
この他、画面の初期表示の完了前にクリックしてしまう(AcceptButtonが設定されているフォームでEnterキーを押していまう)等を誤操作による対応をこのクラスにまとめました。
フォームからの呼び出しについては「ボタン」以外の入力コントロールにも配置しており、イベント輻輳の回避として利用しています。 この件では、初期動作中(Shownイベント等)でメニューコンボの初期インデックスを設定することはよくあると思いますが、 この時にそのメニューコンボのSelectedIndexChangedイベントが動作してしまうのを回避(先頭で脱出)させる役割もあります。
未更新終了チェック関連クラス
(clsCheckNotUpdate2)
これは開発者の「親切心」でやっているような機能です。
例えば、画面上で項目ごとの変更は行なったのに「登録」ボタンをクリックせずにフォームを閉じようとした時に 「キャンセルが選択されました。入力途中の内容は更新されませんが終了しますか?」という機能です。 また、逆に何も変更せずに「登録」ボタンをクリックした時にメッセージを表示させることもできます。
ですが、それぞれのフォームにコードで実装させるのでは開発者によってレベルができてしまうので、 共通クラスとして実装させることにしたものです。
入力コントロールの値の変異をイベントで検知してスイッチをセットしておいて、登録するか閉じるかの段階でこのスイッチを判定してメッセージを表示させる機能なのですが、 フォーム上に入力コントロールがたくさんあっても機能実装の記述に影響がでないように対策を行なってあります。

このページでは、前ページで紹介済みの「ウィンドウ制御クラス(clsAboutWindow1)」「DataGridView制御クラス(clsAboutDataGridView1)」のコードは重複するので提示していません。 それでもフォーム本体のコード記述より、ここから下に提示している共通モジュール・共通クラスのコードの方が長いことがお判りいただけると思います。

共通モジュール・共通クラスに追いやらなくても、次の機能を追加する時にソースコードをコピーして転用すれば済むわけですし、 費用転嫁の上でも見かけ上でもソースコード行数などで開発規模を大きく見せることができるかも知れませんが、 後のメンテナンスのことを考えると「同じ記述があちこちに分散している」というのは良いことではありません。

前後を含めてこのページはデータベースのI/Oに関するサンプルなので、他の記述を増やしたくなかったのですが、 フォームを使う上では仕方ないのである程度合理化した方法で、データベースに影響が少ないフォーム本体関連記述は極力クラス化させてみました。

最初は「共通モジュール(modCommonModule2)」です。

'***************************************************************************************************
'   サンプル用共通モジュール②                                modCommonModule2(Module)
'
'   作成者:井上治  URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
' 変更日付 Rev     変更履歴内容-------------------------------------------------------------------->
' 17/01/15(1.0.0.0)新規作成
' 17/01/22(1.0.1.0)更新登録画面追加に関する対応
'***************************************************************************************************
Module modCommonModule2
    '===============================================================================================
    ' [共通定数]
    ' 日付チェック用定数
    Friend Const g_cnsDefaultDate As Date = #12/31/1899#
    Friend Const g_cnsMinimumDate As Date = #1/1/1900#
    Friend Const g_cnsMaximumDate As Date = #12/31/2049#
    ' 日付NULL時の代替値
    Friend Const g_cnsNullDate As Date = Nothing
    ' 標準フォント名
    Friend Const g_cnsStdFontName As String = "MS ゴシック"
    Friend Const g_cnsStdFontNameP As String = "MS Pゴシック"
    ' 標準フォントサイズ
    Friend Const g_cnsFontSize900 As Single = 9.0F
    Friend Const g_cnsFontSize975 As Single = 9.75F
    ' 共通利用固定文字
    Friend Const g_cnsFormatDate As String = "yyyy-MM-dd"
    Friend Const g_cnsFormatDate2 As String = "yyyy/MM/dd"

    '***********************************************************************************************
    '   ■■■ 一般共通サブ処理 ■■■
    '***********************************************************************************************
    '* 処理名 :GP_AppendMessage
    '* 機能  :エラーメッセージ累積処理
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = 表示用累積メッセージ(String)
    '*      Arg2 = 今回追加メッセージ(String)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:改行を加えながらメッセージを追加する
    '* 注意事項:
    '***********************************************************************************************
    Friend Sub GP_AppendMessage(ByRef strMSG As String, ByRef strADDMSG As String)
        '-------------------------------------------------------------------------------------------
        If strMSG.Length <> 0 Then strMSG &= ControlChars.CrLf
        strMSG &= strADDMSG
    End Sub

    '***********************************************************************************************
    '* 処理名 :FP_EditDate
    '* 機能  :日付表示用編集処理(一覧表示用:デフォルトはyyyy/MM/dd編集)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :編集後の日付(String)
    '* 引数  :Arg1 = 日付値(Object:String)
    '*      Arg2 = 日付フォーマット(String)     ※Option
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月15日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月15日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:Null日付等はブランクが返る
    '***********************************************************************************************
    Friend Function FP_EditDate(ByVal objInDate As Object, _
                                Optional ByVal strDateFormat As String = g_cnsFormatDate2) As String
        '-------------------------------------------------------------------------------------------
        Dim dteDate As Date                                         ' 日付WORK
        Dim strDate As String = String.Empty                        ' 文字列WORK
        ' NULL値でなければ値(文字列)を取り出す
        If ((Not DBNull.Value.Equals(objInDate)) AndAlso (objInDate IsNot Nothing)) Then
            strDate = objInDate.ToString.Trim
        End If
        ' 有効な日付か判定
        If ((strDate.Length <> 0) AndAlso _
            (Date.TryParse(strDate, dteDate)) AndAlso _
            (dteDate >= g_cnsMinimumDate) AndAlso _
            (dteDate < g_cnsMaximumDate)) Then
            ' 日付をフォーマット編集
            Return dteDate.ToString(strDateFormat)
        Else
            ' NGはブランクを返す
            Return String.Empty
        End If
    End Function

    '***********************************************************************************************
    '* 処理名 :GP_ReplaceDateFields
    '* 機能  :日付項目のNullデータ置き換え
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = データテーブルレコード(DataTable.ItemArray) ※戻り値利用
    '*      Arg2 = 日付項目配置INDEXテーブル(Array:Integer)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:Null値をNothingに置き換え、有効日付は内部データ型に置き換える
    '* 注意事項:
    '***********************************************************************************************
    Friend Sub GP_ReplaceDateFields(ByRef tblFLD As Object(), _
                                    ByVal tblIX As Integer())
        '-------------------------------------------------------------------------------------------
        Dim IX As Integer, dteDate As Date
        For IX2 As Integer = 0 To tblIX.GetUpperBound(0)
            IX = tblIX(IX2)
            If DBNull.Value.Equals(tblFLD(IX)) Then
                ' NULLの場合はNothingに置き換え
                tblFLD(IX) = g_cnsNullDate
            Else
                ' 有効日付(NULL以外)の場合は内部日付型で置き換え
                dteDate = tblFLD(IX)
                tblFLD(IX) = dteDate
            End If
        Next IX2
    End Sub

    '***********************************************************************************************
    ' ■■■ コンボボックス関連共通サブ処理 ■■■
    '***********************************************************************************************
    '* 処理名 :GP_SetComboBoxList
    '* 機能  :コンボボックスのリストセット
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = コンボボックス(Object)
    '*      Arg2 = DataTable(Object)
    '*      Arg3 = コードテーブル(Array:String)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:コンボボックスのリスト及びコードテーブルを作成する
    '* 注意事項:コンボはメニューコンボでも利用できるようにObject型としている
    '***********************************************************************************************
    Friend Sub GP_SetComboBoxList(ByRef objComboBox As Object, _
                                  ByRef dbTbl As DataTable, _
                                  ByRef tblCode() As String)
        '-------------------------------------------------------------------------------------------
        Dim intIx As Integer = 0                                    ' テーブルINDEX
        Dim intIxMax As Integer = dbTbl.Rows.Count - 1              ' テーブルINDEX上限
        Dim tblName() As String                                     ' 名称テーブル
        ReDim tblCode(intIxMax), tblName(intIxMax)
        ' レコードを巡回
        Do While intIx <= intIxMax
            tblCode(intIx) = dbTbl.Rows(intIx)(0)                   ' (00)コード
            tblName(intIx) = dbTbl.Rows(intIx)(1)                   ' (01)名称
            ' 次へ
            intIx += 1
        Loop
        '-------------------------------------------------------------------------------------------
        ' コンボボックスのリストセット
        With objComboBox.Items
            ' リストクリア
            If .Count <> 0 Then .Clear()
            .AddRange(tblName)
        End With
    End Sub

    '***********************************************************************************************
    '* 処理名 :GP_SetComboIndexByCode
    '* 機能  :コンボボックスの選択をコードテーブルで行なう
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = コンボボックス(Object)
    '*      Arg2 = 現在コード(String)
    '*      Arg3 = コードテーブル(Array:String)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:コードテーブルで発見した位置INDEXをコンボボックスのSelectedIndexにセット
    '* 注意事項:コンボはメニューコンボでも利用できるようにObject型としている
    '***********************************************************************************************
    Friend Sub GP_SetComboIndexByCode(ByRef objComboBox As Object, _
                                      ByVal strCode As String, _
                                      ByRef tblCode() As String)
        '-------------------------------------------------------------------------------------------
        Dim intIx As Integer = 0                                    ' テーブルINDEX
        Dim intIx2 As Integer = -1                                  ' テーブルINDEX
        Dim intIxMax As Integer = tblCode.GetUpperBound(0)          ' テーブルINDEX上限
        ' コードテーブルを巡回
        Do While intIx <= intIxMax
            ' コード発見か
            If tblCode(intIx) = strCode Then
                intIx2 = intIx
                Exit Do
            End If
            ' 次へ
            intIx += 1
        Loop
        '-------------------------------------------------------------------------------------------
        ' 発見位置をコンボボックスにセット
        objComboBox.SelectedIndex = intIx2
    End Sub

    '----------------------------------------<< End of Source >>------------------------------------
End Module
ここでは登録画面で使用する共通プロシージャ「エラーメッセージ累積処理(GP_AppendMessage)」、「日付項目のNullデータ置き換え(GP_ReplaceDateFields)」、「コンボボックスのリストセット(GP_SetComboBoxList)」、「コンボボックスの選択をコードテーブルで行なう(GP_SetComboIndexByCode)」を追加しています。
特に説明が必要だと思われるのは「日付項目のNullデータ置き換え(GP_ReplaceDateFields)」でしょうか、退職日、終了日のように日付のセットが必須でないフィールドは UPDATE文の編集時にフィールドをセットするかどうかで新旧比較を行なう時に一方がNULLだと型不一致の例外となってしまうのでこれを日付型の最小値で置き換えておくという処理です。

テーブル情報定数のモジュールとして「(modSampleCorp1MDB)」を追加しています。
ここでは、今回使用していない定数的な項目テーブルも含まれています。

'***************************************************************************************************
'   配属一覧サンプル(MDB及びテーブル情報)                       modSampleCorp1MDB(Module)
'
'   作成者:井上治  URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
' 変更日付 Rev     変更履歴内容-------------------------------------------------------------------->
' 17/01/22(1.0.1.0)新規作成
' 17/03/11(1.0.1.0)ACCDBでの変更箇所をコメントで追加する対応
'***************************************************************************************************
Module modSampleCorp1MDB
    '===============================================================================================
    ' MDBファイル情報
    Friend Const g_cnsMdbFileame As String = "SampleCorp1.mdb"
    'Private Const g_cnsMdbFileame As String = "SampleCorp1.accdb" ' ←ACCDBの場合
    Friend Const g_cnsMdbSubFolder As String = "SampleMDB"
    ' テーブルID
    Friend Const g_cnsMST_BUSYO As String = "[MST_BUSYO]"           ' 部署マスタ
    Friend Const g_cnsMST_YAKU As String = "[MST_YAKU]"             ' 役職マスタ
    Friend Const g_cnsMST_SYAIN As String = "[MST_SYAIN]"           ' 社員マスタ
    Friend Const g_cnsMST_HAIZOKU As String = "[MST_HAIZOKU]"       ' 配属マスタ
    '-----------------------------------------------------------------------------------------------
    ' 各テーブルのフィールドIDテーブル
    ' 部署マスタ
    Friend ReadOnly g_tblFld_MST_BUSYO() As String = {"[BUSYO_CD]", "[BUSYO_NM]"}
    ' タイプ(0=文字, 1=数値(整数), 2=数値(実数), 2=Bool, 5=日付, 6=時刻, 8=文字列(要変換), 9=他)
    Friend ReadOnly g_tblFldTyp_MST_BUSYO() As Integer = {0, 8}
    '-------------------------
    ' 役職マスタ
    Friend ReadOnly g_tblFld_MST_YAKU() As String = {"[YAKU_CD]", "[RANK1]", "[RANK2]", "[YAKU_NM]"}
    ' タイプ(0=文字, 1=数値(整数), 2=数値(実数), 2=Bool, 5=日付, 6=時刻, 8=文字列(要変換), 9=他)
    Friend ReadOnly g_tblFldTyp_MST_YAKU() As Integer = {0, 0, 0, 8}
    '-------------------------
    ' 社員マスタ
    Friend ReadOnly g_tblFld_MST_SYAIN() As String = _
        {"[SCD]", "[KANJI_SEI]", "[KANJI_MEI]", "[KANA_SEI]", "[KANA_MEI]", "[SEX]", _
         "[SEINEN_YMD]", "[NYUSYA_YMD]", "[TAISYOKU_YMD]"}
    ' タイプ(0=文字, 1=数値(整数), 2=数値(実数), 2=Bool, 5=日付, 6=時刻, 8=文字列(要変換), 9=他)
    Friend ReadOnly g_tblFldTyp_MST_SYAIN() As Integer = {0, 8, 8, 8, 8, 0, 5, 5, 5}
    '-------------------------
    ' 配属マスタ
    Friend ReadOnly g_tblFld_MST_HAIZOKU() As String = _
        {"[SCD]", "[KAISHI_YMD]", "[SYURYO_YMD]", "[BUSYO_CD]", "[YAKU_CD]"}
    ' タイプ(0=文字, 1=数値(整数), 2=数値(実数), 2=Bool, 5=日付, 6=時刻, 8=文字列(要変換), 9=他)
    Friend ReadOnly g_tblFldTyp_MST_HAIZOKU() As Integer = {0, 5, 5, 0, 0}
    '-------------------------

    '----------------------------------------<< End of Source >>------------------------------------
End Module
ここには今回更新対象でないテーブルのフィールド情報のテーブルも含んでいます。
この「フィールド情報のテーブル」は実際のテーブルのフィールドと属性も順序も一致している必要があり、 これはSQLServer用ツールのExcelSQLServerツール」でテーブル定義を作成する場合なら自動的に作成されます。

次は「データベースI/Oクラス(clsAboutMDB2)」です。

'***************************************************************************************************
'   サンプル用データベースI/O関連定数(MDB用)                   modAboutMDB2(Module)
'
'   作成者:井上治  URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
'   ※この下に「データベースI/Oクラス(MDB用)(clsAboutMDB)」があります
'***************************************************************************************************
' 変更日付 Rev     変更履歴内容-------------------------------------------------------------------->
' 17/01/15(1.0.0.0)新規作成
' 17/01/22(1.0.1.0)FP_GetDataTable等を追加(更新登録機能対応)
'***************************************************************************************************
Imports System.IO
Module modAboutMDB2
    '===============================================================================================
    ' WorkTable名
    Friend Const g_cnsMdbTempTable1 As String = "MdbTempTable1"
    Friend Const g_cnsMdbTempTable2 As String = "MdbTempTable2"
    Friend Const g_cnsMdbTempTable3 As String = "MdbTempTable3"
    ' エラーメッセージ
    Friend Const g_cnsMDBMSG001 As String = "データベースに接続できませんでした。"
    Friend Const g_cnsMDBMSG002 As String = "データベースの更新に失敗しました。"
    Friend Const g_cnsMDBMSG003 As String = "データベースの参照に失敗しました。"
    Friend Const g_cnsMDBMSG011 As String = "このコードのデータは既に登録されています。"
    Friend Const g_cnsMDBMSG012 As String = "このコードのデータは登録されていません。"
    Friend Const g_cnsMDBMSG013 As String = "このコードのデータは既に削除済みです。"
    Friend Const g_cnsMDBMSG021 As String = "出力対象データが存在しません。"
    ' MDB共通利用固定文字
    Friend Const g_cnsKA As String = "("
    Friend Const g_cnsKO As String = ")"
    Friend Const g_cnsKA2 As String = "["
    Friend Const g_cnsKO2 As String = "]"
    Friend Const g_cnsFROM As String = " FROM "
    Friend Const g_cnsWHERE As String = " WHERE "
    Friend Const g_cnsSET As String = " SET "
    Friend Const g_cnsIN_JOIN As String = " INNER JOIN "
    Friend Const g_cnsOUT_JOIN As String = " LEFT OUTER JOIN "
    Friend Const g_cnsAND As String = " AND "
    Friend Const g_cnsOR As String = " OR "
    Friend Const g_cnsSELECT As String = "SELECT "
    Friend Const g_cnsSELECT_AST As String = "SELECT * FROM "
    Friend Const g_cnsINSERT As String = "INSERT INTO "
    Friend Const g_cnsUPDATE As String = "UPDATE "
    Friend Const g_cnsDELETE As String = "DELETE FROM "
    Friend Const g_cnsCOM As String = ","
    Friend Const g_cnsSC As String = "'"
    Friend Const g_cnsCOMSC As String = ",'"
    Friend Const g_cnsSCCOM As String = "',"
    Friend Const g_cnsSCCOMSC As String = "','"
    Friend Const g_cnsNULL As String = "NULL"
    Friend Const g_cnsCOMNULL As String = g_cnsCOM & g_cnsNULL
    Friend Const g_cnsSCCOL As String = "';"
    Friend Const g_cnsCOL As String = ";"
    Friend Const g_cnsKOCOL As String = ");"
    Friend Const g_cnsEQ As String = "="
    Friend Const g_cnsEQSC As String = "='"
    Friend Const g_cnsPERSC As String = "%'"
    Friend Const g_cnsSCPER As String = "'%"
    Friend Const g_cnsSH As String = "#"

    '***********************************************************************************************
    '   ■■■ MDB更新関連サブ処理 ■■■
    '***********************************************************************************************
    '* 処理名 :FP_GetDataTable
    '* 機能  :OleDbCommandからDataTableを取得
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :DataTable(Object)
    '* 引数  :Arg1 = SqlCommand(Object)
    '*      Arg2 = SQLのSELECT文(String)
    '*      Arg3 = データテーブル名(String)         ※Option(※)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:本処理内で例外は判定していない
    '***********************************************************************************************
    Friend Function FP_GetDataTable(ByRef dbCommand As OleDb.OleDbCommand, _
                                    ByVal strSQL As String, _
                                    Optional ByVal strWorkTable As String = g_cnsMdbTempTable1) _
                                    As DataTable
        '-------------------------------------------------------------------------------------------
        dbCommand.CommandText = strSQL
        Using dbDAdp As New OleDb.OleDbDataAdapter, dbDSet As New DataSet
            ' DataSetを取得
            dbDAdp.SelectCommand = dbCommand
            dbDAdp.Fill(dbDSet, strWorkTable)
            ' DataTableを返す
            FP_GetDataTable = dbDSet.Tables(strWorkTable)
        End Using
    End Function

    '***********************************************************************************************
    '* 処理名 :FP_SQLStringSUB
    '* 機能  :SQL文文字列項目補助処理
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :SQL文用項目文字列(String)
    '* 引数  :Arg1 = 入力項目文字列(String)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:Trim処理及びシングルクォーテーション二重化
    '* 注意事項:前後にシングルクォーテーションが付加されます。
    '***********************************************************************************************
    Friend Function FP_SQLStringSUB(ByVal strInText As String) As String
        '-------------------------------------------------------------------------------------------
        Dim strInText2 As String = String.Empty & strInText
        FP_SQLStringSUB = g_cnsSC & strInText2.Trim.Replace("'", "''") & g_cnsSC
    End Function

    '***********************************************************************************************
    '* 処理名 :FP_SQLDateSUB2
    '* 機能  :SQL文日付項目補助処理(MDB用)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :SQL文用項目文字列(String)
    '* 引数  :Arg1 = 入力項目日付(Date)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:Trim処理及び日付書式フォーマット
    '* 注意事項:前後にシングルクォーテーションが付加されます。
    '***********************************************************************************************
    Friend Function FP_SQLDateSUB2(ByVal dteInDate As Date) As String
        '-------------------------------------------------------------------------------------------
        If dteInDate <> g_cnsNullDate Then
            Return g_cnsSH & dteInDate.ToString(g_cnsFormatDate) & g_cnsSH
        Else
            Return g_cnsNULL
        End If
    End Function

    '---------------------------------------<< End of Source >>-------------------------------------
End Module

'***************************************************************************************************
'   サンプル用データベースI/Oクラス(MDB用)                     clsAboutMDB2(Class)
'
'   作成者:井上治  URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
' 変更日付 Rev     変更履歴内容-------------------------------------------------------------------->
' 17/01/15(1.0.0.0)新規作成
' 17/01/22(1.0.1.0)GetConnection、ExecuteSQLErrorの追加(更新登録機能対応)
' 17/03/11(1.0.1.0)ACCDBでの変更箇所をコメントで追加する対応
'***************************************************************************************************
Friend Class clsAboutMDB2
    '===============================================================================================
    Private Const g_cnsMDB_Connect1 = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='"
    'Private Const g_cnsMDB_Connect1 = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" ' ←ACCDBの場合
    '-----------------------------------------------------------------------------------------------
    Private g_strConnectionString As String = ""                    ' 接続文字列
    Private g_objOwnerForm As Form = Nothing                        ' 親フォーム

    '***********************************************************************************************
    '   ■■■ 初期化 ■■■
    '***********************************************************************************************
    '* 処理名 :New
    '* 機能  :初期化
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = 親フォーム(Object)
    '*      Arg2 = MDBファイル名(String)
    '*      Arg3 = MDBサブフォルダ名(String)
    '*      Arg4 = MDBの接続ユーザーID(String)     ※Option
    '*      Arg5 = MDBの接続パスワード(String)     ※Option
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月15日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月15日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Friend Sub New(ByVal objOwnerForm As Form, _
                   ByVal strMdbFilename As String, _
                   ByVal strMdbSubFolder As String, _
                   Optional ByVal strMdbUserId As String = "", _
                   Optional ByVal strMdbPassword As String = "")
        '-------------------------------------------------------------------------------------------
        g_objOwnerForm = objOwnerForm
        ' MDB接続文字列の編集
        g_strConnectionString = FP_GetMdbConnectionString(strMdbFilename, _
                                                          strMdbSubFolder, _
                                                          strMdbUserId, _
                                                          strMdbPassword)
    End Sub

    '***********************************************************************************************
    '   ■■■ OleDbアクセス関連共通サブ処理 ■■■
    '***********************************************************************************************
    '* 処理名 :GetDataTableOle
    '* 機能  :データテーブルを取得(OLE非接続処理)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :処理成否(Boolean)
    '* 引数  :Arg1 = DataTable(Object)                ※Ref参照(戻り値)
    '*      Arg2 = SQL文(String)
    '*      Arg3 = 参照テーブルID(String)           ※カッコ付きテーブル名
    '*      Arg4 = エラーメッセージ(String)         ※Option(エラー表示させない時の通知用)
    '*      Arg5 = データテーブル名(String)         ※Option
    '*      Arg6 = エラー表示スイッチ(Boolean)      ※Option(内部でエラー表示させる)
    '*      Arg7 = 無データエラースイッチ(Boolean)  ※Option(0件をエラー扱いにしない)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月15日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月15日
    '* 更新者 :井上 治
    '* 機能説明:データテーブル名は"MdbTempTable1"がデフォルト
    '* 注意事項:
    '***********************************************************************************************
    Friend Function GetDataTableOle(ByRef dbTbl As DataTable, _
                                    ByVal strSQL As String, _
                                    ByVal strTableName As String, _
                                    Optional ByRef strFatalErrMSG As String = "", _
                                    Optional ByVal strWorkTable As String = g_cnsMdbTempTable1, _
                                    Optional ByVal swDispError As Boolean = True, _
                                    Optional ByVal swNoDataError As Boolean = False) As Boolean
        '-------------------------------------------------------------------------------------------
        Dim strMSG As String = g_cnsMDBMSG001                       ' エラーメッセージ
        dbTbl = Nothing
        Using dbCon As New OleDb.OleDbConnection, dbDSet As New DataSet
            Try
                '-----------------------------------------------------------------------------------
                ' MDBコネクションを取得
                dbCon.ConnectionString = g_strConnectionString
                '-----------------------------------------------------------------------------------
                ' 参照SQLの発行(DataAdapter)
                strMSG = g_cnsMDBMSG003
                Using dbDAdp As New OleDb.OleDbDataAdapter(strSQL, dbCon)
                    ' DataSetを取得
                    dbDAdp.Fill(dbDSet, strWorkTable)
                    ' DataTableを返す
                    dbTbl = dbDSet.Tables(strWorkTable)
                    ' 0件確認
                    If (swNoDataError AndAlso (dbTbl.Rows.Count = 0)) Then
                        ' 0件をエラーとする場合の処置
                        strFatalErrMSG = g_cnsMDBMSG021 & FP_ChangeRoundBrackets(strTableName)
                        ' メッセージ表示
                        If swDispError Then
                            MessageBox.Show(g_objOwnerForm, _
                                            strFatalErrMSG, _
                                            g_objOwnerForm.Text, _
                                            MessageBoxButtons.OK, _
                                            MessageBoxIcon.Error)
                        End If
                        Return False
                    End If
                End Using
                Return True

            Catch ex As Exception
                '-----------------------------------------------------------------------------------
                ' 接続・参照不成功(一般例外)
                strFatalErrMSG = strMSG & FP_ChangeRoundBrackets(strTableName) & _
                    ControlChars.CrLf & ex.Message
                ' メッセージ表示
                If swDispError Then
                    MessageBox.Show(g_objOwnerForm, _
                                    strFatalErrMSG, _
                                    g_objOwnerForm.Text, _
                                    MessageBoxButtons.OK, _
                                    MessageBoxIcon.Error)
                End If
                Return False
            End Try
        End Using
    End Function

    '***********************************************************************************************
    '* 処理名 :GetConnection
    '* 機能  :OleDbConnectionの取得
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :OleDbConnection(Object)
    '* 引数  :Arg1 = 処理成否(Boolean)                ※Ref参照
    '*      Arg2 = エラーメッセージ(String)         ※Option(エラー表示させない時の通知用)
    '*      Arg3 = エラー表示スイッチ(Boolean)      ※Option
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Friend Function GetConnection(ByRef blnResult As Boolean, _
                                  Optional ByRef strFatalErrMSG As String = "", _
                                  Optional ByVal swDispError As Boolean = True) _
                                  As OleDb.OleDbConnection
        '-------------------------------------------------------------------------------------------
        Try
            blnResult = True
            Return New OleDb.OleDbConnection(g_strConnectionString)
        Catch ex As Exception
            strFatalErrMSG = ex.Message
            ' メッセージ表示
            If swDispError Then
                MessageBox.Show(g_objOwnerForm, _
                                strFatalErrMSG, _
                                g_objOwnerForm.Text, _
                                MessageBoxButtons.OK, _
                                MessageBoxIcon.Error)
            End If
            blnResult = False
            Return Nothing
        End Try
    End Function

    '***********************************************************************************************
    '* 処理名 :ExecuteSQLError
    '* 機能  :更新SQLエラー処理(致命エラー扱い)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = エラーメッセージ(String)
    '*      Arg2 = 処理工程(String)
    '*      Arg3 = 更新テーブルID(String)
    '*      Arg5 = SQL文(String)                ※Option
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月22日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Friend Sub ExecuteSQLError(ByVal strErrMessage As String, _
                               ByVal strWork As String, _
                               ByVal strTableId As String, _
                               Optional ByVal strSQL As String = "")
        '-------------------------------------------------------------------------------------------
        Dim strMSG As String = String.Empty                     ' エラーメッセージ
        ' エラーメッセージの編集
        If strWork.Length <> 0 Then
            strMSG = strWork & FP_ChangeRoundBrackets(strTableId) & ControlChars.CrLf & _
                     strErrMessage
        Else
            strMSG = strErrMessage
            If strTableId.Length <> 0 Then
                strMSG &= FP_ChangeRoundBrackets(strTableId)
            End If
        End If
        ' SQL文があれば接続
        If strSQL.Length <> 0 Then
            strMSG &= ControlChars.CrLf & strSQL
        End If
        ' エラーメッセージの表示
        MessageBox.Show(g_objOwnerForm, _
                        strMSG, _
                        g_objOwnerForm.Text, _
                        MessageBoxButtons.OK, _
                        MessageBoxIcon.Error)
    End Sub

    '***********************************************************************************************
    '   ■■■ 共通サブ処理(Private) ■■■
    '***********************************************************************************************
    '* 処理名 :FP_GetMdbConnectionString
    '* 機能  :MDB接続文字列の編集
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :MDB接続文字列(String)
    '* 引数  :Arg1 = MDBファイル名(String)
    '*      Arg2 = マイドキュメント配下のサブフォルダ(String)
    '*      Arg3 = ユーザーID(String)
    '*      Arg4 = パスワード(String)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月15日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:マイドキュメント配下のサブフォルダを指定してMDB接続文字列を編集
    '* 注意事項:
    '***********************************************************************************************
    Private Function FP_GetMdbConnectionString(ByVal strMDBName As String, _
                                               ByVal strSubFolder As String, _
                                               ByVal strUserId As String, _
                                               ByVal strPassword As String) As String
        '-------------------------------------------------------------------------------------------
        Dim strPathname As String = My.Computer.FileSystem.SpecialDirectories.MyDocuments ' フォルダ
        ' サブフォルダ指定あり
        If strSubFolder.Length <> 0 Then
            strPathname = Path.Combine(strPathname, strSubFolder)
        End If
        ' MDBファイル名を接続したフルパス名を編集
        Dim strFilename As String = Path.Combine(strPathname, strMDBName) ' ファイル名
        ' MDBの接続文字列を編集
        Dim strConnectionString As String = g_cnsMDB_Connect1       ' 接続文字列
        strConnectionString &= strFilename & g_cnsSCCOL
        ' ユーザーIDが指定されている
        If strUserId.Length <> 0 Then
            strConnectionString &= "User ID='" & strUserId & g_cnsSCCOL
        End If
        ' パスワードが指定されている
        If strPassword.Length <> 0 Then
            strConnectionString &= "Password='" & strPassword & g_cnsSCCOL
        End If
        Return strConnectionString
    End Function

    '***********************************************************************************************
    '* 処理名 :FP_ChangeRoundBrackets
    '* 機能  :鍵カッコを丸カッコに変換(共通処理)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :変換後文字列(String)
    '* 引数  :Arg1 = 変換前文字列(String)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月15日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月22日
    '* 更新者 :井上 治
    '* 機能説明:例:"[TableName]"を"(TableName)"に変換する(例外メッセージ表示用)
    '* 注意事項:先頭文字が"["でない場合はそのまま返す
    '***********************************************************************************************
    Private Function FP_ChangeRoundBrackets(ByVal strInTableName As String) As String
        '-------------------------------------------------------------------------------------------
        Const cnsKOKA2 As String = "].["
        Const cnsDOT As String = "."
        If strInTableName.Length = 0 Then Return strInTableName
        ' 先頭文字が"["か
        If strInTableName.StartsWith(g_cnsKA2) Then
            ' 中間の"].["を"."のみに変換
            Dim strText As String = strInTableName.Replace(cnsKOKA2, cnsDOT)
            ' 先頭文字が"["の場合は丸カッコに変換する
            Return g_cnsKA & strText.Substring(1, strText.Length - 2) & g_cnsKO
        ElseIf strInTableName.StartsWith(g_cnsKA) Then
            ' 先頭文字が"("の場合はそのまま返す
            Return strInTableName
        ElseIf strInTableName.EndsWith(g_cnsKO2) Then
            ' 右端のみ"]"が付いている場合の対応
            Dim strText As String = strInTableName.Substring(0, strInTableName.Length - 1)
            Return g_cnsKA & strText & g_cnsKO
        Else
            ' 上記以外の場合は"("~")"で挟む
            Return g_cnsKA & strInTableName & g_cnsKO
        End If
    End Function

    '----------------------------------------<< End of Source >>------------------------------------
End Class
クラスの前にあるモジュールに動的にSQL文を編集する時によく使う文字列を定数化させており、 データベースへの接続型参照の「OleDbCommandからDataTableを取得(FP_GetDataTable)」等を追加、 「データベースI/Oクラス(clsAboutMDB2)」本体には、「OleDbConnectionの取得(GetConnection)」「更新SQLエラー処理(致命エラー扱い)(ExecuteSQLError)」を追加しています。

次は「入力コントロールのダブルクリック抑制クラス(clsOmitDoubleClick2)」です。

'***************************************************************************************************
'   入力コントロールのダブルクリック抑制クラス                   clsOmitDoubleClick3(Class)
'
'   ※ボタン等でダブルクリックしてしまうとClickイベントが2回走ってしまうことを抑制するクラス
'     ⇒本クラスはフォームのLoadイベントで実装すること
'
'   作成者:井上治  URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
' 変更日付 Rev     変更履歴内容-------------------------------------------------------------------->
' 17/01/29(1.0.1.0)新規作成
'***************************************************************************************************
Friend Class clsOmitDoubleClick2
    '===============================================================================================
    Private g_objOwnerForm As Form = Nothing                ' 現在フォーム
    '-----------------------------------------------------------------------------------------------
    Private g_swShown As Boolean = False                    ' 初期表示完了スイッチ
    Private g_swFirstShown As Boolean = True                ' 初回表示判定スイッチ
    Private g_swOmitDoubleClick As Boolean = False          ' ダブルクリック抑制スイッチ

    '***********************************************************************************************
    ' ■■■ クラス初期化メソッド ■■■
    '***********************************************************************************************
    '* 処理名 :New
    '* 機能  :初期化
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = Ownerフォーム(Object)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月29日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Friend Sub New(ByRef objOwner As Form)
        '-------------------------------------------------------------------------------------------
        g_objOwnerForm = objOwner                   ' Ownerフォーム
        '-------------------------------------------------------------------------------------------
        ' アプリケーションアイドルイベントの関連付け
        AddHandler Application.Idle, AddressOf Application_Idle
        ' フォームイベント関連付け
        AddHandler g_objOwnerForm.FormClosed, AddressOf Form_FormClosed
    End Sub

    '***********************************************************************************************
    ' ■■■ アプリケーションイベント ■■■
    '***********************************************************************************************
    '* 処理名 :Application_Idle
    '* 機能  :アプリケーションアイドルイベント
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月29日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub Application_Idle(ByVal sender As Object, ByVal e As System.EventArgs)
        '-------------------------------------------------------------------------------------------
        ' ダブルクリック抑制スイッチのクリア
        g_swOmitDoubleClick = False
    End Sub

    '***********************************************************************************************
    ' ■■■ フォームイベント ■■■
    '***********************************************************************************************
    '* 処理名 :Form_FormClosed
    '* 機能  :フォームイベント(FormClosed)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月29日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Private Sub Form_FormClosed(ByVal sender As Object, ByVal e As FormClosedEventArgs)
        '-------------------------------------------------------------------------------------------
        ' アプリケーションアイドルイベントの関連付け解除
        RemoveHandler Application.Idle, AddressOf Application_Idle
    End Sub

    '***********************************************************************************************
    ' ■■■ フォームからの呼び出し処理 ■■■
    '***********************************************************************************************
    '* 処理名 :CheckDoubleClick
    '* 機能  :ダブルクリック等の多重操作の判定とスイッチセット
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :判定結果(Boolean)                           ※True=処理中
    '* 引数  :Arg1 = スイッチセットのオミット(Boolean)    ※True=Omit(Option)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月29日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Friend Function CheckDoubleClick(Optional ByVal blnOmitSet As Boolean = False) As Boolean
        '-------------------------------------------------------------------------------------------
        CheckDoubleClick = False
        ' ダブルクリック等の多重操作の判定
        If g_swOmitDoubleClick OrElse Not g_swShown Then Return True
        ' ※g_swOmitDoubleClickはTrueのまま放置で良い
        If Not blnOmitSet Then
            g_swOmitDoubleClick = True
        End If
    End Function

    '***********************************************************************************************
    '   プロパティ
    '***********************************************************************************************
    ' 初期表示完了スイッチ(Boolean)
    '-----------------------------------------------------------------------------------------------
    Friend Property Shown As Boolean
        Set(value As Boolean)
            g_swShown = value
        End Set
        Get
            Return g_swShown
        End Get
    End Property

    '===============================================================================================
    ' 初回表示判定スイッチ(Boolean)
    '-----------------------------------------------------------------------------------------------
    Friend Property FirstShown As Boolean
        Set(value As Boolean)
            g_swFirstShown = value
        End Set
        Get
            Return g_swFirstShown
        End Get
    End Property

    '===============================================================================================
    ' ダブルクリック抑制スイッチ(Boolean)
    '-----------------------------------------------------------------------------------------------
    Friend Property OmitDoubleClick As Boolean
        Set(value As Boolean)
            g_swOmitDoubleClick = value
        End Set
        Get
            Return g_swOmitDoubleClick
        End Get
    End Property

    '----------------------------------------<< End of Source >>------------------------------------
End Class
このクラスは先の説明の通り、前ページにはないものです。
.NET Frameworkでは「ボタン」に記述上ではDoubleClickイベントがあるのですが、実際には動作することはなく、 操作上でダブルクリックしてしまうと、普通のClickイベントが複数回走ってしまうという問題があります。
例えば、その「ボタン」のClickイベントの先頭でスイッチ変数をセット、最後でスイッチ変数をリセットさせるように対応したとして、 先頭のスイッチ変数セットの前で既にスイッチ変数がセットされていたら以降の処理を行なわないように記述すれば解決できるように思われがちですが、 実際のClickイベントの動作はバッファリングされているようでこの方法では解決できません。
本件はいろいろ調べた結果なのですが、アプリケーションレベルのIdleイベントまで待って先のスイッチ変数をクリアということです。
このため、「スイッチ変数セット」や「スイッチ変数の判定」などをクラス側に追いやって、各コントロールのClickイベントの先頭には 1行だけのクラス側プロシージャの呼び出し記述を加えるだけでこれらの機能が実現できるように対応したものです。
バッチ処理の起動メッセージなどでは、この段階でIdleイベントに至ってしまうので、 クラス側のスイッチ変数を外部操作させるプロパティも実装させています。

次は「未更新終了チェック関連クラス(clsCheckNotUpdate2)」です。

'***************************************************************************************************
'   未更新終了チェック関連クラス                              clsCheckNotUpdate2(Class)
'
'   ※登録ボタンをClickせずに終了しようとする時の警告表示対応の変数、共通プロシージャ
'     ⇒本クラスはフォームのNewイベントでInitializeComponentの直後に実装すること
'
'   作成者:井上治  URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
' 変更日付 Rev     変更履歴内容-------------------------------------------------------------------->
' 17/01/29(1.0.1.0)新規作成
'***************************************************************************************************
Friend Class clsCheckNotUpdate2
    '-----------------------------------------------------------------------------------------------
    Private g_objOwnerForm As Form = Nothing                    ' 現在フォーム
    Private g_cnsProgTitle As String = "未更新終了チェック"     ' フォームタイトル 
    Private g_swNotUpdate As Boolean = False                    ' 未登録終了警告スイッチ
    Private g_swFatalError As Boolean = False                   ' 致命例外判定スイッチ
    Private g_swLockItem As Boolean = False                     ' 項目ロックスイッチ
    ' 未更新終了警告メッセージ
    Private g_strNotUpdateMSG As String = "「キャンセル」が選択されました。" & ControlChars.CrLf & _
                "入力途中の内容は更新されませんが終了しますか?" ' メッセージ

    '***********************************************************************************************
    ' ■■■ クラス初期化メソッド ■■■
    '***********************************************************************************************
    '* 処理名 :New
    '* 機能  :初期化
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = Ownerフォーム(Object)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月29日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Friend Sub New(ByRef objOwner As Form)
        '-------------------------------------------------------------------------------------------
        g_objOwnerForm = objOwner                   ' Ownerフォーム
        g_cnsProgTitle = objOwner.Text              ' フォームタイトル
        '-------------------------------------------------------------------------------------------
        ' 未登録終了警告スイッチ対応イベントハンドラ追加
        Call GP_ControlsAddHandler(objOwner)
        ' FormClosingイベントハンドラ追加
        AddHandler CType(objOwner, Form).FormClosing, AddressOf Form_FormClosing
        '-------------------------------------------------------------------------------------------
        g_swNotUpdate = False
        g_swFatalError = False
    End Sub

    '***********************************************************************************************
    ' ■■■ サブ処理 ■■■
    '***********************************************************************************************
    '* 処理名 :GP_ControlsAddHandler
    '* 機能  :入力コントロールへのイベントハンドラ追加処理
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = 所属するコンテナ(Object)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月29日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:コンテナ上の各入力コントロールにイベントハンドラを追加(変異検出用)
    '* 注意事項:本処理は再帰動作
    '***********************************************************************************************
    Private Sub GP_ControlsAddHandler(ByVal objContainer As Object)
        '-------------------------------------------------------------------------------------------
        ' コントロールの種別によって変異検出用のイベントハンドラを追加
        For Each objCont As Control In objContainer.Controls
            If TypeOf objCont Is TextBox Then
                ' テキストボックス
                AddHandler CType(objCont, TextBox).TextChanged, AddressOf Controls_ValueChanged
                '-----------------------------------------------------------------------------------
            ElseIf TypeOf objCont Is ComboBox Then
                ' コンボボックス
                With CType(objCont, ComboBox)
                    AddHandler .SelectedIndexChanged, AddressOf Controls_ValueChanged
                    AddHandler .TextChanged, AddressOf Controls_ValueChanged
                End With
                '-----------------------------------------------------------------------------------
            ElseIf TypeOf objCont Is CheckBox Then
                ' チェックボックス
                AddHandler CType(objCont, CheckBox).CheckedChanged, AddressOf Controls_ValueChanged
                '-----------------------------------------------------------------------------------
            ElseIf TypeOf objCont Is RadioButton Then
                ' ラジオボタン
                AddHandler CType(objCont, RadioButton).CheckedChanged, AddressOf Controls_ValueChanged
                '-----------------------------------------------------------------------------------
            ElseIf TypeOf objCont Is DataGridView Then
                ' DataGridView
                AddHandler CType(objCont, DataGridView).CellValueChanged, AddressOf Controls_ValueChanged
                '-----------------------------------------------------------------------------------
            ElseIf TypeOf objCont Is MaskedTextBox Then
                ' マスクドテキストボックス(DatePickerJP等)
                AddHandler CType(objCont, MaskedTextBox).TextChanged, AddressOf Controls_ValueChanged
                '-----------------------------------------------------------------------------------
            ElseIf TypeOf objCont Is RichTextBox Then
                ' リッチテキストボックス
                AddHandler CType(objCont, RichTextBox).TextChanged, AddressOf Controls_ValueChanged
                '-----------------------------------------------------------------------------------
            ElseIf TypeOf objCont Is ListBox Then
                ' リストボックス
                AddHandler CType(objCont, ListBox).SelectedIndexChanged, AddressOf Controls_ValueChanged
                '-----------------------------------------------------------------------------------
            ElseIf TypeOf objCont Is NumericUpDown Then
                ' ニューメリックアップダウン
                AddHandler CType(objCont, NumericUpDown).ValueChanged, AddressOf Controls_ValueChanged
                '-----------------------------------------------------------------------------------
            ElseIf TypeOf objCont Is DateTimePicker Then
                ' DateTimePicker
                AddHandler CType(objCont, DateTimePicker).ValueChanged, AddressOf Controls_ValueChanged
                '-----------------------------------------------------------------------------------
            ElseIf ((TypeOf objCont Is TabControl) OrElse _
                    (TypeOf objCont Is TabPage) OrElse _
                    (TypeOf objCont Is GroupBox) OrElse _
                    (TypeOf objCont Is Panel) OrElse _
                    (TypeOf objCont Is TableLayoutPanel) OrElse _
                    (TypeOf objCont Is FlowLayoutPanel) OrElse _
                    (TypeOf objCont Is SplitContainer) OrElse _
                    (TypeOf objCont Is UserControl)) Then
                ' コンテナ時は再帰呼び出し
                Call GP_ControlsAddHandler(objCont)
                '-----------------------------------------------------------------------------------
            End If
        Next objCont
    End Sub

    '***********************************************************************************************
    '   ■■■ イベント
    '***********************************************************************************************
    '* 処理名 :Controls_ValueChanged
    '* 機能  :各入力コントロールの値変更イベント処理
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月29日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:どれかの入力コントロールで更新入力があったかを判断するイベント
    '* 注意事項:Form_Loadイベントで全入力コントロールのイベントハンドラ追加を行なう前提
    '***********************************************************************************************
    Friend Sub Controls_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs)
        '-------------------------------------------------------------------------------------------
        ' 未登録終了警告スイッチをセット
        If Not g_swNotUpdate Then
            g_swNotUpdate = True
        End If
    End Sub

    '***********************************************************************************************
    '* 処理名 :Form_FormClosing
    '* 機能  :フォーム閉じる動作(FormClosing)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年01月29日
    '* 作成者 :井上 治
    '* 更新日 :2017年01月29日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Friend Sub Form_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs)
        '-------------------------------------------------------------------------------------------
        ' 未登録終了警告スイッチの判定
        e.Cancel = False
        If (g_swNotUpdate AndAlso Not g_swLockItem AndAlso Not g_swFatalError) Then
            If MessageBox.Show( _
                g_objOwnerForm, _
                g_strNotUpdateMSG, _
                g_cnsProgTitle, _
                MessageBoxButtons.YesNo, _
                MessageBoxIcon.Information) <> Windows.Forms.DialogResult.Yes Then
                e.Cancel = True
                Exit Sub
            End If
        End If
    End Sub

    '***********************************************************************************************
    '   ■■■ 参照・設定プロパティ
    '***********************************************************************************************
    '   未登録終了警告スイッチ(Boolean)
    '-----------------------------------------------------------------------------------------------
    Friend Property NotUpdate() As Boolean
        Get
            Return g_swNotUpdate
        End Get
        Set(ByVal value As Boolean)
            g_swNotUpdate = value
        End Set
    End Property

    '===============================================================================================
    '   致命例外判定スイッチ(Boolean)
    '-----------------------------------------------------------------------------------------------
    Friend Property FatalError As Boolean
        Get
            Return g_swFatalError
        End Get
        Set(value As Boolean)
            g_swFatalError = value
        End Set
    End Property

    '===============================================================================================
    '   項目ロックスイッチ(Boolean)
    '-----------------------------------------------------------------------------------------------
    Friend WriteOnly Property LockItem() As Boolean
        Set(ByVal value As Boolean)
            g_swLockItem = value
        End Set
    End Property

    '===============================================================================================
    '   未登録終了警告メッセージ(String)
    '-----------------------------------------------------------------------------------------------
    Friend WriteOnly Property NotUpdateMSG() As String
        Set(ByVal value As String)
            g_strNotUpdateMSG = value
        End Set
    End Property

    '---------------------------------------<< End of Source >>-------------------------------------
End Class

このクラスも先の説明の通り、前ページにはないものです。
この「未更新終了チェック関連クラス(clsCheckNotUpdate2)」が結構長いクラスだとお判りのことだと思います。 本来、フォーム上に記述するイベントをクラス内で消化させるように組み立てているため、フォーム上ではクラスの初期化以外はあまり多くの記述を行なわなくても良いようになっています。

ACCDBで実行したい方へ  
サンプルをダウンロードすると、ACCDB用に変更するための記述を2箇所コメントで埋め込んであります。

    Private Const g_cnsMDB_Connect1 = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='"
    'Private Const g_cnsMDB_Connect1 = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" ' ←ACCDBの場合


    ' MDBファイル情報
    Private Const g_cnsMdbFileame As String = "SampleCorp1.mdb"
    'Private Const g_cnsMdbFileame As String = "SampleCorp1.accdb" ' ←ACCDBの場合
この2箇所をコメント側の記述に変更して、先頭で説明している「SampleMDB」フォルダ内に「SampleCorp1.accdb」を配置して実行してみて下さい。 「SampleCorp1.accdb」は、こちらの頁末から定義文書とセットでダウンロードできます。
フォーム画面が崩れる時は...   近年の「高DPIノートPC」をWindows7以前のバージョンで使用している場合は、 フォームやコントロールの大きさが変わらないのに文字だけ大きくなってしまうのでフォーム画面が崩れた状態に表示されてしまいます。
Windows8.1以降ではOS側がスクリーンごとのDPI設定を含めて補正してしまうので問題ないのですが、 Windows7以前ではプログラム側で対策を講じる必要があります。
本件についてはDPI制御の問題」をご覧下さい。