Microsoft Access 掲示板

Error#: 3134 INSERT INTO ステートメントの構文エラーです。

20 コメント
views
4 フォロー

いつもお世話になっております。

hatenaさん、りんごさん、
数週間前に「テーブル変更後、読み込まなくなりました」というタイトルで
相談に乗って頂きありがとうございました。

その際、基本を学ぶようアドバイスを頂き、一から作り直すことも考えたのですが
仕事の都合、今回のシステムで運用をすることになりそうです。
勤務先の基幹システムとリンクを貼る際に、色々と難関がありましたが、
なんとか完成に辿り着けそうです。お二人のおかげです!

さて、今回もVBAの相談です。
(基本を学ぶようアドバイス頂いているのにスミマセン😅

題記のエラーが発生しています。
以前、こちらで同じような相談をしたばかりなのですが
ご教授ください!

今回も本を参考に打ち込んだつもりなのですが、、、。

Private Sub btn追加_Click()
If IsNull(Me.cmb依頼者.Value) Or IsNull(Me.cmb希望処置.Value) _
    Or IsNull(Me.txtW_No.Value) Then
      MsgBox "必要項目が入力されていません", vbInformation, "確認"
      Exit Sub
    End If
    
    Dim sqlList As Collection
    Set sqlList = New Collection
    
    Dim strSQL As String
    strSQL = _
      "INSERT INTO T_依頼 ([依頼日], [依頼者], [W_No], [W_Noロット], [品名], [希望処置], [補足説明]) " & _
      "VALUES(" & _
        "#" & Me.txt依頼日.Value & "#, " & _
        "'" & Me.cmb依頼者.Value & "', " & _
        "'" & Me.txtW_No.Value & "', " & _
        "'" & Me.txtW_Noロット.Value & "', " & _
        "'" & Me.txt品名.Value & "', " & _
        "'" & Me.cmb希望処置.Value & "', " & _
        "'" & Me.txt補足説明.Value & "');"
    sqlList.Add strSQL
    
    Dim errMsg As String
    errMsg = tryExecute(sqlList)
    
    If errMsg <> "" Then
      MsgBox errMsg, vbCritical, "エラー"
      Exit Sub
    End If
    
    Set sqlList = New Collection
    Me.txt依頼ID.Value = DMax("依頼ID", "T_依頼")
    
    Dim i As Long
    For i = 1 To 10
      If Not IsNull(Me("cmb1依頼理由" & i).Value) Then
        strSQL = _
          "INSERT INTO T_依頼詳細([依頼ID], [ロット番号], [ロット枝], [依頼理由_1], [依頼理由_2], [依頼理由_3], [詳細補足説明], [最終更新日]) " & _
          "VALUES(" & _
            Me.txt依頼ID.Value & ", " & _
            "'" & Me("txtロット番号" & i).Value & "', " & _
            Me("cmbロット枝" & i).Value & ", " & _
            Me("cmb1依頼理由" & i).Value & ", " & _
            Me("cmb2依頼理由" & i).Value & ", " & _
            Me("cmb3依頼理由" & i).Value & ", " & _
            Me("txt巻き長さ" & i).Value & ", " & _
            Me("txt詳細補足説明" & i).Value & ");"
        sqlList.Add strSQL
      End If
    Next i
    
    errMsg = tryExecute(sqlList)
    
    If errMsg <> "" Then
      MsgBox errMsg, vbCritical, "エラー"
      Exit Sub
    End If
    
    Call loadForm
    MsgBox "追加しました", vbInformation, "完了"
End Sub
wazawaza
作成: 2022/06/13 (月) 18:23:58
通報 ...
1

そのエラーが出たとき、デバッグボタンを押すと、どの行がハイライトされますか。

あと、tryExecute という関数はないので、ユーザー定義関数と思いますが、そのコードも提示してください。

2
wazawaza 2022/06/13 (月) 21:59:52

hatenaさん、お世話になります。
ハイライトされなくて困っております。

下記がtryExecuteになります。
よろしくお願いします。

Functionさんさん tryExecute(sqlList As Collection) As String
  On Error GoTo ErrorHandler
  
  Dim daoDb As DAO.Database
  Set daoDb = CurrentDb
  
  Dim strSQL As Variant
  For Each strSQL In sqlList
    daoDb.Execute strSQL
  Next strSQL
  
  tryExecute = ""
  
  GoTo Finally
  
ErrorHandler:
  tryExecute = "Error #: " & Err.Number & vbNewLine & vbNewLine & Err.Description
  
Finally:
  If Not daoDb Is Nothing Then
    daoDb.Close
    Set daoDb = Nothing
  End If

End Function
3
hiroton 2022/06/14 (火) 08:59:10 5f374@f966d

SQL実行時のエラーメッセージなので実際に実行されるSQL文を確認しましょう

Excel VBA 入門講座 - イミディエイトウィンドウ(pc-users.netさん)

ありがちなのは入力チェック漏れでNULLが指定されててVALUES(1234,,'ABC')みたいな文になってるとかですね


後半のSQL文ですが

フィールド囲み文字リテラルの型
[依頼ID]Me.txt依頼ID.Value(なし)数値
[ロット番号]Me("txtロット番号" & i).Value'文字列
[ロット枝]Me("cmbロット枝" & i).Value(なし)数値
[依頼理由_1]Me("cmb1依頼理由" & i).Value(なし)数値
[依頼理由_2]Me("cmb2依頼理由" & i).Value(なし)数値
[依頼理由_3]Me("cmb3依頼理由" & i).Value(なし)数値
[詳細補足説明]Me("txt巻き長さ" & i).Value(なし)数値
[最終更新日]Me("txt詳細補足説明" & i).Value(なし)数値

特に最後の2項目、間違っていませんか?


ついでにエラーについて

このコードではプログラムが中断されるようなエラーは発生していません。記述通りに動作して、MsgBox errMsg, vbCritical, "エラー"の文が実行されメッセージボックスが表示されているだけです。当然「デバッグ」ボタンも表示されませんし、ハイライト表示もできません

「そのようにプログラミングされている」ことを理解する必要があるでしょう

4
hatena 2022/06/14 (火) 09:40:16 修正

ハイライトされなくて困っております。

  On Error GoTo ErrorHandler
でエラー処理しているので、エラー場所はわからなくなります。
デバッグするときは、この行はコメントアウトしてから、実行するとエラー箇所がハイライトされるはずです。

おそらく、

   daoDb.Execute strSQL

がハイライトされるはずです。
ここで、strSQLに格納されているSQL文が間違っているのではと推測できます。

あとは、hirotonさんのご指摘を確認してみてください。

5
wazawaza 2022/06/14 (火) 22:13:34

hirotonさん、
ありがとうございます!
後半のSQL文、最後の2項目
確かに間違っていました。

まずはSQL文自体を理解していないと
今回の間違いは見つけられないと
思います。発見まで暫く時間帯が
掛かりそうです😅

hatenaさん、
コメントアウトしたら、見事に
ハイライトされました。

先程も書きましたが
やはりSQL文を勉強をしないと
お二人から折角アドバイスを受けても
噛み砕けないままになってしまい
そうです。

もう少し勉強したのち、
今回のものを見直してみます!

ありがとうございました!

6
hatena 2022/06/15 (水) 12:08:53 修正

VBA内でのSQL文、めんどくさいですよね。
& でつなげなければいけない
データ型によって、#'で囲まなければならない
未入力だったばあい Null に変換したりする必要がある
など・・・

最初のSQLの場合は、1件のレコードを追加するだけですので、自分なら、recordset.AddNewを使いますね。

そうすると下記のようなコードですみます。

    Dim rs As Dao.Recordset

    Set rs = CurrentDb.OpenRecordset("T_依頼")
    rs.AddNew
    rs!依頼日 = Me.txt依頼日.Value
    rs!依頼者 = Me.cmb依頼者.Value
    rs!W_No = Me.txtW_No.Value
    rs!W_Noロット = Me.txtW_Noロット.Value
    rs!品名 = Me.txt品名.Value
    rs!希望処置 = Me.cmb希望処置.Value
    rs!補足説明 = Me.txt補足説明.Value
    rs.Update
    rs.Close

どうでしょうか。こちらの方がはるかにシンプルで読みやすいと思いませんか。

さらに、テキストボックス名をフィールド名と同じにしておけば、下記のようにいちいちフィールド名やテキストボックス名を記述する必要もなくなります。

    Dim rs As DAO.Recordset, fld As DAO.Field
    Set rs = CurrentDb.OpenRecordset("T_売上")
    rs.AddNew
    For Each fld In rs.Fields
        fld.Value = Me(fld.Name).Value
    Next
    rs.Update
    rs.Close

2つめのSQL文は下記のようになります。

テキストボックス名は、
フィールド名の後に1~10の数字を付加したものにしておいて、

    Set rs = CurrentDb.OpenRecordset("T_依頼詳細")
    Dim i As Long
    For i = 1 To 10
      If Not IsNull(Me("依頼理由" & i).Value) Then
          rs.AddNew
          For Each fld In rs.Fields
              fld.Value = Me(fld.Name & i).Value
          Next
          rs.Update
      End If
    Next i
    rs.Close
7
wazawaza 2022/06/16 (木) 12:08:25

hatenaさん
ご丁寧な解説、本当に助かります!

前回相談にのって頂いたdbも、最初このSQLで躓き
別の本に載っていた「recordset.AddNew」で試したところ、
上手くいったので、もしや?と思っておりましたが
その“もしや”をご提案いただき、やっぱり!となりました。

さて、早速実践してみましたが、エラーです。
実行時エラー’2465’:
指定した式で参照されている’L0000002'フィールドが見つかりません。

下の文がデバックで黄色になります。
fld.Value = Me(依頼ID).Value

間違っていますね・・・😅
今現在、下記内容になっております


'##############################
'### レコード移動時のID採番 ###
'##############################

Private Sub Form_Current()

    Me.btn最新ID取得.Enabled = True  '「btn最新ID取得」を使用可能に
    Me.btn追加.Enabled = False       '「btn追加」を使用不可に(最新ID取得に導く仕掛け)
    
     Const prefix As String = "L"  '「laminate」の頭文字 "L"
    
    Dim maxID As String
    maxID = DMax("依頼ID", "T_依頼")  '最終IDを取り出す
    
    Dim lastNum As Long
    lastNum = Replace(maxID, prefix, "")  '最終IDから頭文字"L"を除き、数値型へ代入する
    
    Dim newID As String
    newID = prefix & Format(lastNum + 1, "0000000")  '+1して桁を揃えて頭文字"L"と結合
    
    Me.依頼ID.DefaultValue = "'" & newID & "'"  '既定値へ代入
End Sub

'##########################
'### 初期化プロシージャ ###
'##########################

Private Sub initializeForm()       '初期化

    Me.依頼日.Value = Null              '「依頼日」をクリア
    Me.依頼者.Value = Null              '「依頼者」をクリア
    Me.希望処置.Value = Null            '「希望処置」をクリア
    Me.WNo.Value = Null                 '「WNo」をクリア
    Me.W_No.Value = Null                '「W_No」をクリア
    Me.W_Noロット.Value = Null          '「W_Noロット」をクリア
    Me.品名.Value = Null                '「品名」をクリア
    Me.補足説明.Value = Null            '「補足説明」をクリア
    
    Dim i As Long
    For i = 1 To 10
        Me("詳細ID" & i).Value = Null           '「詳細ID」をクリア
        Me("ロット番号" & i).Value = Null       '「ロット番号」をクリア
        Me("ロット枝" & i).Value = Null         '「ロット枝」をクリア
        Me("依頼理由_1" & i).Value = Null       '「依頼理由_1」をクリア
        Me("依頼理由_2" & i).Value = Null       '「依頼理由_2」をクリア
        Me("依頼理由_3" & i).Value = Null       '「依頼理由_3」をクリア
        Me("巻き長さ" & i).Value = Null         '「巻き長さ」をクリア
        Me("詳細補足説明" & i).Value = Null     '「詳細補足説明」をクリア
    Next i
    
    Me.btn最新ID取得.Enabled = True        '「btn最新ID取得」を使用可能に
    Me.btn追加.Enabled = False             '「btn追加」を使用不可に
    Me.btn閉じる.Enabled = True            '「btn閉じる」を使用可能に
    Me.依頼ID.Enabled = True               '「依頼ID」を使用可能に
End Sub


'##############################################
'### 「txtW_No」「txt品名」に対する入力補助 ###
'##############################################

Private Sub WNo_AfterUpdate()    '「cmbW_No」の更新後処理
    W_No.Value = WNo.Column(7)   '「W_No」に7列目を表示。編集不可で設定中
    品名.Value = WNo.Column(2)   '「品名」に2列目を表示。編集不可で設定中
End Sub

Private Sub btn追加_Click()
    If IsNull(Me.依頼者.Value) Or IsNull(Me.希望処置.Value) _
    Or IsNull(Me.W_No.Value) Then
      MsgBox "必要項目が入力されていません", vbInformation, "確認"
      Exit Sub
    End If
    
    Dim rs As DAO.Recordset, fld As DAO.Field
    Set rs = CurrentDb.OpenRecordset("T_依頼")
        rs.AddNew
        For Each fld In rs.Fields
         fld.Value = Me(依頼ID).Value
         fld.Value = Me(依頼日).Value
         fld.Value = Me(依頼者).Value
         fld.Value = Me(W_No).Column(2)
         fld.Value = Me(W_Noロット).Value
         fld.Value = Me(品名).Value
         fld.Value = Me(希望処置).Value
         fld.Value = Me(補足説明).Value
    Next
    rs.Update
    rs.Close
    
    Set rs = CurrentDb.OpenRecordset("T_依頼詳細")
    Dim i As Long
    For i = 1 To 10
      If Not IsNull(Me("依頼理由_1" & i).Value) Then
        rs.AddNew
        For Each fld In rs.Fields
           fld.Value = Me("依頼ID" & i).Value
           fld.Value = Me("ロット番号" & i).Value
           fld.Value = Me("ロット枝" & i).Value
           fld.Value = Me("依頼理由_1" & i).Column(1)
           fld.Value = Me("依頼理由_2" & i).Column(1)
           fld.Value = Me("依頼理由_3" & i).Column(1)
           fld.Value = Me("巻き長さ" & i).Value
           fld.Value = Me("詳細補足説明" & i).Value
           fld.Value = Now
        Next
        rs.Update
      End If
    Next i
    rs.Close

    MsgBox "追加しました", vbInformation, "完了"
End Sub

8
wazawaza 2022/06/16 (木) 12:10:25

fld.Value = Now は無視してください。

9

下記の部分でエラーということですね。

    Dim rs As DAO.Recordset, fld As DAO.Field
    Set rs = CurrentDb.OpenRecordset("T_依頼")
        rs.AddNew
        For Each fld In rs.Fields
         fld.Value = Me(依頼ID).Value '←ここでエラー
         fld.Value = Me(依頼日).Value
         fld.Value = Me(依頼者).Value
         fld.Value = Me(W_No).Column(2)
         fld.Value = Me(W_Noロット).Value
         fld.Value = Me(品名).Value
         fld.Value = Me(希望処置).Value
         fld.Value = Me(補足説明).Value
    Next
    rs.Update
    rs.Close

前回の回答で、
一つずつ、フィールドに対応するテキストボックスの値を代入する方法と、
フィールド名とテキストボックスを同じにしておいて、いちいち指定せずにループで代入しておく方法、
の2つを提案したのですが、それを混ぜ和せてしまっては正常に動きません。

前者の方法でいくなら、上記のコードは、下記のようになります。(フィールド名とテキストボックス名は同じにしてあるという前提です)

    Dim rs As DAO.Recordset, fld As DAO.Field
    Set rs = CurrentDb.OpenRecordset("T_依頼")
    rs.AddNew
    rs("依頼ID").Value = Me.依頼ID.Value
    rs("依頼日").Value = Me.依頼日.Value
    rs("依頼者").Value = Me.依頼者.Value
    rs("W_No").Value = Me.W_No.Value 'コンボボックスの連結列をフィールドのデータと合うものにしておく
    rs("W_Noロット").Value = Me.W_Noロット.Value
    rs("品名").Value = Me.品名.Value
    rs("希望処置").Value = Me.希望処置.Value
    rs("補足説明").Value = Me.補足説明.Value
    rs.Update
    rs.Close
10

後者の方法なら、下記のコードになります。

入力しないフィールドがある場合  "フィールド1,フィールド2" とカンマ区切りで指定してください。
全てのフィールドに入力するならIf文は不要です。

    Dim rs As DAO.Recordset, fld As DAO.Field
    Set rs = CurrentDb.OpenRecordset("T_依頼")
    rs.AddNew
    For Each fld In rs.Fields
        If Not "フィールド1,フィールド2" Like "*" & fld.Name & "*" Then
            fld.Value = Me(fld.Name).Value
        End If
    Next
    rs.Update
    rs.Close
11

すっきりして見やすいですねぇなんて思いながら見てましたが、OpenRecordsetにはSQL文も指定できるのでハイブリッドでやるのもいいかなぁと思いました

    strSQL = "SELECT 依頼ID, 依頼日, 依頼者, W_No, W_Noロット, 品名, 希望処置, 補足説明 FROM T_依頼;"

    Set rs = CurrentDb.OpenRecordset(strSQL)
    rs.AddNew
    For Each fld In rs.Fields
        fld.Value = Me(fld.Name).Value
    Next
    rs.Update

不要な分を弾く処理よりは必要分を記述していくほうが分かりやすいかと
単純なSELECT文なので間違いも起きにくいですし

それから、エイリアス使ってひねってやるとフィールド名とコントロール名が別でも良かったりしますね

    strSQL = "SELECT 依頼ID AS txt依頼ID, 依頼日 AS txt依頼日, 依頼者 AS cmb依頼者, W_No AS txtW_No, W_Noロット AS txtW_Noロット, 品名 AS txt品名, 希望処置 AS cmb希望処置, 補足説明 AS txt補足説明 FROM T_依頼;"

フォームに配置できないフィールド名(詳細)とかはこの手法で


質問だと後半のINSERTは「依頼ID」が共通で最大10レコード登録な処理ですかね(追記内容だと「依頼ID」にもiがついているので真実は不明)
これの時は、別入力処理も使っていくことになりそうです

    Dim strSQL As String
    strSQL = "SELECT 依頼ID, ロット番号 AS txtロット番号, ロット枝 AS cmbロット枝, 依頼理由_1 AS cmb1依頼理由, 依頼理由_2 AS cmb2依頼理由, 依頼理由_3 AS cmb3依頼理由, 巻き長さ AS txt巻き長さ, 詳細補足説明 AS txt詳細補足説明, 更新日時 FROM T_依頼詳細"
    Set rs = CurrentDb.OpenRecordset(strSQL)
    Dim i As Long
    For i = 1 To 10
        If Not IsNull(Me("依頼理由" & i).Value) Then
            rs.AddNew
            For Each fld In rs.Fields
                If Not ",依頼ID,更新日時," Like "*," & fld.Name & ",*" Then
                    fld.Value = Me(fld.Name & i).Value
                End If
            Next
            '//レコード共通項目や計算結果を入れるものは個別に処理
            rs!依頼ID.Value = Me!依頼ID.Value
            rs!更新日時.Value = Now
            rs.Update
        End If
    Next i
    rs.Close

更新日時のような計算で求めるものも外に出して個別に処理ですかねぇ


Like判定は誤動作しそうで怖い。完全一致で判定(Select Caseで列挙するとか)したくなります

12
wazawaza 2022/06/17 (金) 11:09:57

お二方、ありがとうございます!
まずは、hatenaさん。
ご提案の文を使わせていただいたところ、T_依頼にはレコードが入りますが、

Private Sub btn追加_Click()
    If IsNull(Me.依頼者.Value) Or IsNull(Me.希望処置.Value) _
    Or IsNull(Me.W_No.Value) Then
      MsgBox "必要項目が入力されていません", vbInformation, "確認"
      Exit Sub
    End If
    
    Dim rs As DAO.Recordset, fld As DAO.Field
    Set rs = CurrentDb.OpenRecordset("T_依頼")
    rs.AddNew
    rs("依頼ID").Value = Me.依頼ID.Value
    rs("依頼日").Value = Me.依頼日.Value
    rs("依頼者").Value = Me.依頼者.Value
    rs("W_No").Value = Me.W_No.Value 'コンボボックスの連結列をフィールドのデータと合うものにしておく
    rs("W_Noロット").Value = Me.W_Noロット.Value
    rs("品名").Value = Me.品名.Value
    rs("希望処置").Value = Me.希望処置.Value
    rs("補足説明").Value = Me.補足説明.Value
    rs.Update
    rs.Close
    
    Set rs = CurrentDb.OpenRecordset("T_依頼詳細")
    Dim i As Long
    For i = 1 To 10
      If Not IsNull(Me("依頼理由_1" & i).Value) Then
        rs.AddNew
        For Each fld In rs.Fields
           fld.Value = Me("詳細ID" & i).Value
           fld.Value = Me("ロット番号" & i).Value
           fld.Value = Me("ロット枝" & i).Value
           fld.Value = Me("依頼理由_1" & i).Column(1)
           fld.Value = Me("依頼理由_2" & i).Column(1)
           fld.Value = Me("依頼理由_3" & i).Column(1)
           fld.Value = Me("巻き長さ" & i).Value
           fld.Value = Me("詳細補足説明" & i).Value
           fld.Value = Now
        Next
        rs.Update
      End If
    Next i
    rs.Close

    MsgBox "追加しました", vbInformation, "完了"
End Sub

子レコード側を入力したのち、追加ボタンを押すと
実行時エラー’3022’インデックス、主キー、またはリレーションで重複する値が、、、
が表示され、下記がエラーとなりました。

Dim rs As DAO.Recordset, fld As DAO.Field
    Set rs = CurrentDb.OpenRecordset("T_依頼")
    rs.AddNew
    rs("依頼ID").Value = Me.依頼ID.Value
    rs("依頼日").Value = Me.依頼日.Value
    rs("依頼者").Value = Me.依頼者.Value
    rs("W_No").Value = Me.W_No.Value 'コンボボックスの連結列をフィールドのデータと合うものにしておく
    rs("W_Noロット").Value = Me.W_Noロット.Value
    rs("品名").Value = Me.品名.Value
    rs("希望処置").Value = Me.希望処置.Value
    rs("補足説明").Value = Me.補足説明.Value
    rs.Update   '←ここでエラー
    rs.Close

よろしくお願いします!

13
wazawaza 2022/06/17 (金) 11:24:25

hirotonさん
ご提案の文を使わせて頂きました。
“コンパイルエラー 変数が定義されていません。”
初歩的な質問で、大変恐縮ですが
間違えを指摘していただけますか?

Private Sub btn追加_Click()
    
   Dim strSQL As String
   strSQL = "SELECT 依頼ID AS txt依頼ID, 依頼日 AS txt依頼日, 依頼者 AS cmb依頼者, 作業長承認 AS cmb作業長承認, W_No AS txtW_No, W_Noロット AS txtW_Noロット, 品名 AS txt品名, 希望処置 AS cmb希望処置, 補足説明 AS txt補足説明 FROM T_依頼;"
    Set rs = CurrentDb.OpenRecordset(strSQL) '← rs = が反転されます。
    rs.AddNew
    For Each fld In rs.Fields
        fld.Value = Me(fld.Name).Value
    Next
    rs.Update
    
    Dim strSQL As String
    strSQL = "SELECT 依頼ID, ロット番号 AS txtロット番号, ロット枝 AS cmbロット枝, 依頼理由_1 AS cmb1依頼理由, 依頼理由_2 AS cmb2依頼理由, 依頼理由_3 AS cmb3依頼理由, 巻き長さ AS txt巻き長さ, 詳細補足説明 AS txt詳細補足説明, 更新日時 FROM T_依頼詳細"
    Set rs = CurrentDb.OpenRecordset(strSQL)
    Dim i As Long
    For i = 1 To 10
        If Not IsNull(Me("cmb1依頼理由" & i).Value) Then
            rs.AddNew
            For Each fld In rs.Fields
                If Not ",依頼ID,更新日時," Like "*," & fld.Name & ",*" Then
                    fld.Value = Me(fld.Name & i).Value
                End If
            Next
            '//レコード共通項目や計算結果を入れるものは個別に処理
            rs!依頼ID.Value = Me!依頼ID.Value
            rs!更新日時.Value = Now
            rs.Update
        End If
    Next i
    rs.Close
    
    MsgBox "追加しました", vbInformation, "完了"
End Sub
15

コンパイルエラーなのでコンパイルをしてみましょう
画像1

エラーの場所が反転してわかると思います
画像2

回答はコード案の一部を記載したものなので、前後の処理や必要な変数宣言は別途記述する必要があります。変数の使いまわしもしてるので記述を整理する必要もあるでしょう

プロシージャをすべて記述するなら

Private Sub btn追加_Click()
    Dim rs As DAO.Recordset, fld As DAO.Field '//この行が不足
    Dim strSQL As String
    strSQL = "SELECT 依頼ID AS txt依頼ID, 依頼日 AS txt依頼日, 依頼者 AS cmb依頼者, 作業長承認 AS cmb作業長承認, W_No AS txtW_No, W_Noロット AS txtW_Noロット, 品名 AS txt品名, 希望処置 AS cmb希望処置, 補足説明 AS txt補足説明 FROM T_依頼;"
    Set rs = CurrentDb.OpenRecordset(strSQL)
    rs.AddNew
    For Each fld In rs.Fields
        fld.Value = Me(fld.Name).Value
    Next
    rs.Update
    
'    Dim strSQL As String '//すでに宣言しているので不要
    strSQL = "SELECT 依頼ID, ロット番号 AS txtロット番号, ロット枝 AS cmbロット枝, 依頼理由_1 AS cmb1依頼理由, 依頼理由_2 AS cmb2依頼理由, 依頼理由_3 AS cmb3依頼理由, 巻き長さ AS txt巻き長さ, 詳細補足説明 AS txt詳細補足説明 FROM T_依頼詳細"
    Set rs = CurrentDb.OpenRecordset(strSQL)
    Dim i As Long
    For i = 1 To 10
        If Not IsNull(Me("cmb1依頼理由" & i).Value) Then
            rs.AddNew
            For Each fld In rs.Fields
                If Not ",依頼ID,更新日時," Like "*," & fld.Name & ",*" Then
                    fld.Value = Me(fld.Name & i).Value
                End If
            Next
            'レコード共通項目や計算結果を入れるものは個別に処理
            rs!依頼ID.Value = Me!依頼ID.Value
            rs.Update
        End If
    Next i
    rs.Close
    
    MsgBox "追加しました", vbInformation, "完了"
End Sub

「更新日時」フィールドは例示のための記述なので削除しました

14

実行時エラー’3022’インデックス、主キー、またはリレーションで重複する値が、、、
が表示され、下記がエラーとなりました。

T_依頼 の主キーフィールドはなんでしょうか。
エラーメッセージのとおりだと思いますので、主キーフィールドの値が重複していないか、確認してみてください。

16
wazawaza 2022/06/18 (土) 14:36:59

hirotonさん、ありがとうございます。
再度挑戦しました。
すると「パラメーターが少なすぎます。9を指定してください。」です。

Private Sub btn追加_Click()
    
   Dim rs As DAO.Recordset, fld As DAO.Field
   Dim strSQL As String
   strSQL = "SELECT 依頼ID AS txt依頼ID, 依頼日 AS txt依頼日, 依頼者 AS cmb依頼者, 作業長承認 AS cmb作業長承認, W_No AS txtW_No, W_Noロット AS txtW_Noロット, 品名 AS txt品名, 希望処置 AS cmb希望処置, 補足説明 AS txt補足説明 FROM T_依頼;"
    Set rs = CurrentDb.OpenRecordset(strSQL)
    rs.AddNew
    For Each fld In rs.Fields
        fld.Value = Me(fld.Name).Value
    Next
    rs.Update

    strSQL = "SELECT 詳細ID As txt詳細ID, ロット番号 AS txtロット番号, ロット枝 AS cmbロット枝, 依頼理由_1 AS cmb1依頼理由, 依頼理由_2 AS cmb2依頼理由, 依頼理由_3 AS cmb3依頼理由, 巻き長さ AS txt巻き長さ, 詳細補足説明 AS txt詳細補足説明, T_依頼詳細"
    Set rs = CurrentDb.OpenRecordset(strSQL)    '←ここでエラー
    Dim i As Long
    For i = 1 To 10
        If Not IsNull(Me("cmb1依頼理由" & i).Value) Then
            rs.AddNew
            For Each fld In rs.Fields
                If Not ",依頼ID,最終更新日," Like "*," & fld.Name & ",*" Then
                    fld.Value = Me(fld.Name & i).Value
                End If
            Next
            '//レコード共通項目や計算結果を入れるものは個別に処理
            rs!依頼ID.Value = Me!txt依頼ID.Value
            rs!最終更新日.Value = Now
            rs.Update
        End If
    Next i
    rs.Close
    
    MsgBox "追加しました", vbInformation, "完了"
End Sub

hatenaさん、ありがとうございます。
実行時エラー’3022’は、同じ主キーで一生懸命、登録を試みてました😅
スミマセン😅😅

で、再度挑戦しました。
すると「バリアント型ではない変数にNull値を代入しようとしました」です。

Private Sub btn追加_Click()
    If IsNull(Me.依頼者.Value) Or IsNull(Me.希望処置.Value) _
    Or IsNull(Me.W_No.Value) Then
      MsgBox "必要項目が入力されていません", vbInformation, "確認"
      Exit Sub
    End If
    
    Dim rs As DAO.Recordset, fld As DAO.Field
    Set rs = CurrentDb.OpenRecordset("T_依頼")
    rs.AddNew
    rs("依頼ID").Value = Me.依頼ID.Value
    rs("依頼日").Value = Me.依頼日.Value
    rs("依頼者").Value = Me.依頼者.Value
    rs("W_No").Value = Me.W_No.Value 'コンボボックスの連結列をフィールドのデータと合うものにしておく
    rs("W_Noロット").Value = Me.W_Noロット.Value
    rs("品名").Value = Me.品名.Value
    rs("希望処置").Value = Me.希望処置.Value
    rs("補足説明").Value = Me.補足説明.Value
    rs.Update
    rs.Close
    
    Set rs = CurrentDb.OpenRecordset("T_依頼詳細")
    Dim i As Long
    For i = 1 To 10
      If Not IsNull(Me("依頼理由_1" & i).Value) Then
        rs.AddNew
        For Each fld In rs.Fields
           fld.Value = Me("詳細ID" & i).Value          '←ここでエラー
           fld.Value = Me("ロット番号" & i).Value
           fld.Value = Me("ロット枝" & i).Value
           fld.Value = Me("依頼理由_1" & i).Column(1)
           fld.Value = Me("依頼理由_2" & i).Column(1)
           fld.Value = Me("依頼理由_3" & i).Column(1)
           fld.Value = Me("巻き長さ" & i).Value
           fld.Value = Me("詳細補足説明" & i).Value
           fld.Value = Now
        Next
        rs.Update
      End If
    Next i
    rs.Close

    MsgBox "追加しました", vbInformation, "完了"
End Sub

親テーブル「T_依頼」

進捗状況依頼ID依頼日依頼者作業長承認加工承認仕上承認生管承認W_NoW_Noロット品名希望処置補足説明
Yes/No型短いテキスト日付/時刻型短いテキスト短いテキスト短いテキスト短いテキスト短いテキスト短いテキスト短いテキスト短いテキスト短いテキスト長いテキスト

子テーブル「T_依頼詳細」

詳細ID依頼IDロット番号ロット枝依頼理由_1依頼理由_2依頼理由_3巻き長さ詳細補足説明検品作業者検品フィードバックPEコメント最終更新日
オートナンバー型短いテキスト短いテキスト短いテキスト短いテキスト短いテキスト短いテキスト数値型長いテキスト短いテキスト長いテキスト長いテキスト日付/時刻型
17
りんご 2022/06/20 (月) 11:17:45 c564b@0e907

 パラメーターエラーは、念の為、SQL文の不備から見直してみるのはどうでしょう?
 Null値代入エラーは、取り敢えず、For Each〜Nextを使わないコードに戻してみるのはどうでしょう?
 これで解決しない、もしくは、新しいエラーが出た場合は、For i = 1 To 10 〜Nextを使わないコードに戻してみるのはどうでしょう?
 それでも駄目なら、兎にも角にも、まずは、繰り返し処理を使わないコードを泥臭く書かないと色々難しいでしょう。
 最後に、今回のシステムに関して質問を続ける場合や別のシステムに関して質問をする場合、リレーションシップの画面をスクリーンショットして提示して下さい。リレーションシップが設定されていない場合、質問する意味がありませんので、これが大事です。

18
    For i = 1 To 10
      If Not IsNull(Me("依頼理由_1" & i).Value) Then
        rs.AddNew
        For Each fld In rs.Fields
           fld.Value = Me("詳細ID" & i).Value          '←ここでエラー
           fld.Value = Me("ロット番号" & i).Value
           fld.Value = Me("ロット枝" & i).Value
           fld.Value = Me("依頼理由_1" & i).Column(1)
           fld.Value = Me("依頼理由_2" & i).Column(1)
           fld.Value = Me("依頼理由_3" & i).Column(1)
           fld.Value = Me("巻き長さ" & i).Value
           fld.Value = Me("詳細補足説明" & i).Value
           fld.Value = Now
        Next
        rs.Update
      End If
    Next i

上記のコード、私が前に指摘した、

一つずつ、フィールドに対応するテキストボックスの値を代入する方法と、
フィールド名とテキストボックスを同じにしておいて、いちいち指定せずにループで代入しておく方法、
が、ごちゃまぜになってます。

一つずつ、フィールドに対応するテキストボックスの値を代入する方法に書き換えましょう。
後者の方法はまだちょっと敷居が高いようです。

    For i = 1 To 10
      If Not IsNull(Me("依頼理由_1" & i).Value) Then
        rs.AddNew
        rs("詳細ID").Value = Me("詳細ID" & i).Value
        rs("ロット番号").Value = Me("ロット番号" & i).Value
        rs("ロット枝").Value = Me("ロット枝" & i).Value
        rs("依頼理由_1").Value = Me("依頼理由_1" & i).Column(1)
        rs("依頼理由_2").Value = Me("依頼理由_2" & i).Column(1)
        rs("依頼理由_3").Value = Me("依頼理由_3" & i).Column(1)
        rs("巻き長さ").Value = Me("巻き長さ" & i).Value
        rs("詳細補足説明").Value = Me("詳細補足説明" & i).Value
        rs.Update
      End If
    Next i

そのうえでエラーが出たら、エラーメッセージとどの行でエラーが出たか提示してください。

19
wazawaza 2022/06/21 (火) 11:51:51

hatenaさん、
ありがとうございました!
上手くいきました👍

hirotonさん、
ありがとうございます!

りんごさん、
ご指摘ありがとうございます!
今後はリレーションなど、詳細も提示しつつ
質問するようにします。

今回は仕事の都合、時間もないので
hatenaさんのご提案のやり方で進めてみます。

皆さま、ご協力有り難うございました。
SQLはいまの私には難易度高いですね💦

勉強します!

20
りんご 2022/06/21 (火) 18:00:53 c564b@0e907 >> 19

今回は仕事の都合、時間もないので

 最低限の保証を確認しておかないと危険です。これまでのチグハグな様子を見ていると、このシステムは最初から全部壊れている可能性が高いと、容易に予想出来ます。立ち止まって、再考するのはどうでしょう?努力と時間はもっと大切に。