Microsoft Access 掲示板

VBAでSQL更新 / 4

16 コメント
views
4 フォロー
4
ビギナー 2024/06/27 (木) 08:56:31 ddfe5@b96a9

SK様 実行はDoCmd.RunSQL strSQL1 でしてます。明らかに間違ってのカンマを削除したら更新できました(初歩的なミスでした。) すみませんでした。あと SQL部の[Forms]![S_1]![c1~C4]を変数にした場合はどう記述するといいでしょうか? これが上手く出来なくて

通報 ...
  • 7

    T_1テーブルの上記フィールドを非連結フォームに入力値に更新したい

    SQL部の[Forms]![S_1]![c1~C4]を変数にした場合はどう記述するといいでしょうか?

    各非連結コントロールの値を「 SQL 文におけるリテラル」として組み込みたい、
    という意味でおっしゃっているのであれば、その SQL の実行時において、
    いずれかの非連結コントロールの値が Null であることを許容するか否か次第です。

    単純に Null 値をそのまま文字列連結させてしまうと、実行時に構文エラーが
    発生する可能性が極めて高いでしょう。

  • 8
    '非連結フォーム[S_1]のフォームモジュール
    Option Compare Database
    Option Explicit
    
    Private Const SourceTableName As String = "T_1"
    
    'コマンドボタン[cmdUpdate]の[クリック時]イベント
    Private Sub cmdUpdate_Click()
    On Error GoTo Err_cmdUpdate_Click
    
        '入力チェック処理を実行し、その結果が False だった場合
        If InputCheck() = False Then
            'このプロシージャを抜ける
            Exit Sub
        End If
    
        Dim lngResult As VbMsgBoxResult
    
        '実行確認ダイアログを表示し、どのボタンがクリックされたかを受け取る
        lngResult = MsgBox("レコードの更新を実行しますか?", _
                            vbQuestion + vbYesNo + vbDefaultButton2, _
                            "実行確認")
    
        '[いいえ]ボタンがクリックされた場合
        If lngResult = vbNo Then
            'このプロシージャを抜ける
            Exit Sub
        End If
    
        Dim strSQL As String
    
        'UPDATE 文の生成処理を実行し、その結果を変数 strSQL に渡す
        strSQL = CreateUpdateStatement()
    
        '生成に失敗した場合
        If strSQL = "" Then
            'このプロシージャを抜ける
            Exit Sub
        End If
    
        Debug.Print strSQL
    
        DoCmd.SetWarnings False
        'SQL 文の実行
        DoCmd.RunSQL strSQL
        DoCmd.SetWarnings True
    
        MsgBox "レコードが更新されました。", _
               vbInformation, _
               "実行完了"
    
    '終了処理
    Exit_cmdUpdate_Click:
    On Error Resume Next
    
        DoCmd.SetWarnings True
    
        Exit Sub
    
    'エラー時処理
    Err_cmdUpdate_Click:
    
        Dim strErrTitle As String
        Dim strErrMsg As String
    
        strErrTitle = "実行時エラー (" & Me.Name & ".cmdUpdate_Click)"
        strErrMsg = Err.Number & ": " & Err.Description
    
        Debug.Print strErrTitle
        Debug.Print strErrMsg
    
        MsgBox strErrMsg, vbCritical, strErrTitle
    
        Resume Exit_cmdUpdate_Click
    End Sub
    
  • 9
    '各コントロールの入力状態をチェックする関数。
    '全てのコントロールの値が適切であれば True、そうでなければ False を返す
    Private Function InputCheck() As Boolean
    On Error GoTo Err_InputCheck
    
        InputCheck = False
    
        '[txtID]のチェック(オートナンバー型の主キー[ID]と照応)
        With Me![txtID]
            
            If IsNull(.Value) = True Then
                MsgBox "[ID]が入力されていません。", _
                       vbExclamation, _
                       "入力エラー"
                .SetFocus
                Exit Function
            End If
            
            If IsNumeric(.Value) = False Then
                MsgBox "数値データに変換できない文字列が[ID]に入力されています。", _
                       vbExclamation, _
                       "入力エラー"
                .SetFocus
                Exit Function
            End If
    
            If DCount("*", SourceTableName, "[ID]=" & CLng(.Value)) = 0 Then
                MsgBox "テーブル[" & SourceTableName & "]上に、[ID]の値が" & CLng(.Value) & "であるレコードは存在しません。", _
                       vbExclamation, _
                       "入力エラー"
                .SetFocus
                Exit Function
            End If
    
        End With
    
        '[c1]のチェック(数値型フィールド[F1]と照応)
        With Me![c1]
            
            If Nz(.Value, "") <> "" Then
                If IsNumeric(.Value) = False Then
                    MsgBox "数値データに変換できない文字列が[F1]に入力されています。", _
                           vbExclamation, _
                           "入力エラー"
                    .SetFocus
                    Exit Function
                End If
            End If
    
        End With
    
        '[c2]のチェック(通貨型フィールド[F2]と照応)
        With Me![c2]
            
            If Nz(.Value, "") <> "" Then
                If IsNumeric(.Value) = False Then
                    MsgBox "数値データに変換できない文字列が[F2]に入力されています。", _
                           vbExclamation, _
                           "入力エラー"
                    .SetFocus
                    Exit Function
                End If
            End If
    
        End With
    
        '[c3]のチェック(日付/時刻型フィールド[F3]と照応)
        With Me![c3]
            
            If Nz(.Value, "") <> "" Then
                If IsDate(.Value) = False Then
                    MsgBox "日時データに変換できない値が[F3]に入力されています。", _
                           vbExclamation, _
                           "入力エラー"
                    .SetFocus
                    Exit Function
                End If
            End If
    
        End With
    
        InputCheck = True
    
    '終了処理
    Exit_InputCheck:
    
        Exit Function
    
    'エラー時処理
    Err_InputCheck:
    
        InputCheck = False
    
        Dim strErrTitle As String
        Dim strErrMsg As String
    
        strErrTitle = "実行時エラー (" & Me.Name & ".InputCheck)"
        strErrMsg = Err.Number & ": " & Err.Description
    
        Debug.Print strErrTitle
        Debug.Print strErrMsg
    
        MsgBox strErrMsg, vbCritical, strErrTitle
    
    End Function
    
  • 10
    '各コントロールの値に応じた UPDATE 文を生成する関数
    Private Function CreateUpdateStatement() As String
    On Error GoTo Err_CreateUpdateStatement
    
        CreateUpdateStatement = ""
    
        Dim strUpdateClause As String
        Dim strSetClause As String
        Dim strWhereClause As String
    
        With Me
            
            'UPDATE 句の設定
            strUpdateClause = "UPDATE [T_1] "
            
            'ここから SET 句の設定
            strSetClause = ""
            
            '[F1]に対する代入式の設定
            If IsNumeric(![c1].Value) = True Then
                strSetClause = strSetClause & ", " & _
                               "[F1]=" & CDec(![c1].Value)
            Else
                strSetClause = strSetClause & ", " & _
                               "[F1]=Null"
            End If
            
            '[F2]に対する代入式の設定
            If IsNumeric(![c2].Value) = True Then
                strSetClause = strSetClause & ", " & _
                               "[F2]=" & CCur(![c2].Value)
            Else
                strSetClause = ", " & _
                               "[F2]=Null"
            End If
            
            '[F3]に対する代入式の設定
            If IsDate(![c3].Value) = True Then
                strSetClause = strSetClause & ", " & _
                               "[F3]=#" & Format(![c3].Value, "yyyy/mm/dd hh:nn:ss") & "#"
            Else
                strSetClause = strSetClause & ", " & _
                               "[F3]=Null"
            End If
            
            '[F4]に対する代入式の設定
            If Nz(![c4].Value, "") <> "" Then
                strSetClause = strSetClause & ", " & _
                               "[F4]='" & Replace(![c4].Value, "'", "''", 1, -1, vbBinaryCompare) & "'"
            Else
                strSetClause = strSetClause & ", " & _
                               "[F4]=Null"
            End If
            
            strSetClause = "SET " & Mid(strSetClause, 2) & " "
            
            'ここまで SET 句の設定
            
            'ここから WHERE 句の設定
            
            If IsNumeric(![txtID].Value) = True Then
                strWhereClause = "WHERE [ID]=" & CLng(![txtID].Value)
            Else
                '[ID]の指定が正しくなければ戻り値を空文字のまま終了
                Exit Function
            End If
            
            'ここまで WHERE 句の設定
    
        End With
            
        'UPDATE 句、SET 句、WHERE 句を連結して 1 つの SQL 文とした結果を戻り値として返す
        CreateUpdateStatement = strUpdateClause & vbCrLf & _
                                strSetClause & vbCrLf & _
                                strWhereClause & ";"
    
    '終了処理
    Exit_CreateUpdateStatement:
    
        Exit Function
    
    'エラー時処理
    Err_CreateUpdateStatement:
    
        Dim strErrTitle As String
        Dim strErrMsg As String
    
        strErrTitle = "実行時エラー (" & Me.Name & ".CreateUpdateStatement)"
        strErrMsg = Err.Number & ": " & Err.Description
    
        Debug.Print strErrTitle
        Debug.Print strErrMsg
    
        MsgBox strErrMsg, vbCritical, strErrTitle
    
        CreateUpdateStatement = ""
    
    End Function
    
    12

    1箇所修正。

    strUpdateClause = "UPDATE [T_1] "

            strUpdateClause = "UPDATE [" & SourceTableName & "] "
    
    13

    もう1箇所。

                strSetClause = ", " & _
                               "[F2]=Null"

                strSetClause = strSetClause & ", " & _
                               "[F2]=Null"
    
  • 11

    各コントロールの入力チェック、コントロールの値に応じた条件分岐、
    文字列に含まれる引用符のエスケープ処理などを考慮するのであれば、
    以上のサンプルのような形となるでしょう。

    ただ私個人の見解としては、こういうまどろっこしい文字列連結を行うコードを
    記述するより、パラメータクエリを実行するようにした方が良いと思います。