実行時エラー 3020の対策

このQ&Aのポイント
  • 実行時エラー 3020の対策方法を解説します。
  • アクセス2003で発生する実行時エラー 3020の原因と解決策を紹介します。
  • 実行時エラー 3020が発生する場合の対処法を説明します。
回答を見る
  • ベストアンサー

実行時エラー 3020の対策

アクセス2003で次のエラーが発生します。 実行時エラー 3020 Update または CancelUpdateメソッドには、対応するAddNewまたはEditメソッドが必要です。 以下のソースは、「テスト」フォームにtestフィールドがある簡単なデータベースですが、全レコードを最初から最後までtestフィールドの先頭に"abc "を付加するというものです。 Public Sub Test() Dim form_name as String Dim frmObj As Form Dim rstObj As Recordset Dim fld_dat As String form_name = "テスト" DoCmd.OpenForm form_name Set frmObj = Application.Forms(form_name) Set rstObj = frmObj.Recordset '先頭のレコードに移動する DoCmd.GoToRecord acDataForm, form_name, acFirst Do fld_dat = rstObj.Fields("test").Value fld_dat = "abc " & fld_dat rstObj.Fields("test").Value = fld_dat '<--- *** ここでエラー *** '次のレコード DoCmd.GoToRecord acDataForm, form_name, acNext DoEvents Loop While frmObj.NewRecord = False End Sub

  • hdkoa
  • お礼率0% (1/117)

質問者が選んだベストアンサー

  • ベストアンサー
  • DexMachina
  • ベストアンサー率73% (1287/1744)
回答No.1

RecordSetを使って編集をするのでしたら、エラーメッセージに出ている通り、 Editメソッドを使用する必要があります。 (また、レコード移動にはGotoRecordではなくMoveFirstやMoveNextが必要) 逆にフォーム上で処理するのでしたら、フィールドではなくコントロールへの 代入にする必要があります。 提示されたコードでは、この2通りの方法がごっちゃになってしまっています。 とりあえず、(画面描写が入る分、処理は遅くなるものの)私が使い慣れていると いうことで、後者のコードを参考に載せます。 ('「test」フィールドをコントロールソースとするコントロールの名を「Test」としました) Sub テスト() Dim form_name As String Dim frmObj As Form Dim Cntl As Control Dim fld_dat As String form_name = "テスト" DoCmd.OpenForm form_name Set frmObj = Application.Forms(form_name) Set Cntl = frmObj.Controls("Test")   DoCmd.GoToRecord acDataForm, form_name, acFirst '万が一レコード未入力(全削除)後に実行してもエラーにならないよう、 '条件を「Loop」側から「Do」側に移動しました。 Do While frmObj.NewRecord = False   fld_dat = Cntl.Value   fld_dat = "abc " & fld_dat   Cntl.Value = fld_dat   DoCmd.GoToRecord acDataForm, form_name, acNext   DoEvents Loop End Sub ・・・以上です。 ただ、今回のように追加する文字列がすべて同じなのでしたら、更新クエリを 使用した方が効率がよいように思います。 (「テスト」フォームのレコードソースを「テーブルA」としました) *フォームの更新後イベント等を利用して、他のフィールドを連動更新する場合は不可* Sub テスト2() On Error Goto エラー処理 Dim StrSQL As String Dim form_name As String StrSQL = "UPDATE テーブルA SET テーブルA.test = 'abc ' & テーブルA!test;" form_name = "テスト" DoCmd.SetWarnings False  'SQL実行時の確認メッセージを停止 DoCmd.RunSQL StrSQL DoCmd.OpenForm form_name  'フォームを開いて更新後の状態を確認 終了処理:   DoCmd.SetWarnings True  'メッセージの停止を解除   Exit Sub エラー処理:   MsgBox Err & ":" Error$,,"テスト(Sub)"   Resume 終了処理 End Sub なお、コードでSQL文を作成するのではなく、予めクエリとして保存しておいて、 それを使うこともできます。 (この場合は、「DoCmd.RunSQL StrSQL」を「DoCmd.OpenQuery "(クエリ名)"」に変更し、  他のStrSQLが出てくる行はすべて削除します)

関連するQ&A

  • GoToRecordでサブフォームを指定したい

    Fフォームの中にSF詳細という名前のサブフォームを埋め込んでいます。 このサブフォームに対して、 指定したレコードに移動したいのですが DoCmd.GoToRecord acDataForm, Form_SF詳細, acGoTo, 3 DoCmd.GoToRecord acDataForm, Forms("Fフォーム").Controls("SF詳細").Form, acGoTo, 3 DoCmd.GoToRecord acDataForm, "SF詳細", acGoTo, 3 全部エラーになり、うまくいきません。 正しい記述の仕方を教えてください。

  • VBAに「maqBox」を追加したい

    検索結果フォーム「未来」を開くフォーム「マスター」に配した、コマンドボタンのイベントに下記の記述「OKWaveで過去にアドバイス頂いた」をしています。この記述に「("指定したレコードはありません")」を表示させたいと思います。WEBを参照したりしてやってみましたが上手く出来ませんでした。 ツール:Access2007 フォーム名:未来 Private Sub コマンド27_Click() If Me.CurrentRecord < Me.Recordset.RecordCount Then DoCmd.GoToRecord acDataForm, Me.Name, acNext End If End Sub [やってみたこと「VBA知識なし」] Private Sub コマンド27_Click() If Me.CurrentRecord < Me.Recordset.RecordCount Then DoCmd.GoToRecord acDataForm, Me.Name, acNext End If   MsgBox ("指定したレコードはありません") End Sub 上記の書込だと検索結果のレコードの数だけ移動時にメッセージが出る。 以上ですが、宜しくお願いします。

  • サブフォームでフィルタしたデータのCSV出力

    ACCESS2007 で テーブル  T_リスト name      cate aaa       123 sss       543 rtyy      45t4 フォーム 顧客があり リスト作成ボタンがあります フォーム顧客の中に フォーム電話帳サブフォームがあり データソースはT_リストです その都度手動でフィルタをかける作業をします リスト作成ボタンを押すとフィルタで抽出したデータだけを CSVに書き出したいと思っています。 下記実行しましたが、 T_リストの一行目のデータしか書き出しません DoCmd.OpenForm ("電話帳サブフォーム")でフォームを出さずに実行したいです どなたかよいアドバイスをお願いします。 Private Sub コマンド1_Click() Dim F As Variant Dim Field1 As String Dim Field2 As String Dim M As Double Dim i As Double Field1 = "name" Field2 = "cat1" M = Me![電話帳サブフォーム].Form.Recordset.RecordCount Open "C:\ListMaker\out.csv" For Output As #1 Write #1, Field1, Field2 DoCmd.OpenForm ("電話帳サブフォーム") Me.[電話帳サブフォーム].SetFocus For i = 1 To M DoCmd.GoToRecord acDataForm, "Me.電話帳サブフォーム", acGoTo, i Write #1, Me![電話帳サブフォーム]![name] i = i + 1 Next DoCmd.GoToRecord , , acFirst Close #1 End Sub

  • Accessサブフォームのレコード移動

    Accessにおいて、サブフォームのレコードの移動方法をどなたか教えてもらえませんか。「Forms![メインフォーム名]![サブフォーム名].Form.SetFocus DoCmd.GoToRecord acDataForm, "サブフォーム名", acNext」とコーディングしたのですがダメでした。よろしくお願い致します。

  • アクセスでクロス集計をレポートにする方法

    一応過去質問を調べましたがうまくいかず、よろしくお願いします。 3種類のテーブルをもとに、それぞれについて3種類のクロス集計を行い、 その3つのクエリを一つのクエリにしました。この選択クエリを作る際は、 *をドラッグして全てのフィールドを表示させています。 そのクエリをレコードソースとして、 空のラベル、テキストボックスを必要数置いて以下のようにレポートを作成しましたが、うまくいきません。 どなたか、ご指導ください。 Private Sub Report_Open(Cancel As Integer) Dim db As DAO.Database Dim qd As DAO.QueryDef Dim cnt As Integer Dim fld As DAO.Field Set db = CurrentDb() Set qd = db.QueryDefs(Me.RecordSource) For cnt = 1 To qd.Fields.Count - 1 Set fld = qd.Fields(cnt) Me("Label" & cnt).Caption = fld.Name Me("Field" & cnt).ControlSource = fld.Name Next End Sub

  • AccessVBAのCurrentDbメソッドでエラーになります

    Windows2000、Access2000を使っています。 オンラインヘルプを参考に作った下記のプログラムを走らせると、Set db = CurrentDbのところで「実行時エラー13:型が一致しません」のエラーになります。どうしてでしょう。 Sub b() Dim db As DAO.Database Dim tdf As DAO.TableDef Dim fld As DAO.Field Set db = CurrentDb Set tdf = db.TableDefs("テーブル1") For Each fld In tdf.Fields Debug.Print fld.Name Next fld End Sub 参照設定を見ると、Microsoft dao 3.0 Object LibraryにチェックがついていますのでDAOは使えるはずなんですが・・・。

  • サブフォームに対してGoToRecordするには?

    フォームに対してRequeryすると先頭のレコードへ移動してしまうので Requeryする前のレコードの番号を取得して Requery後にそのレコード番号へ移動したいのですが Sub test() i = Forms("Form").Controls("SubForm").Form.CurrentRecord Forms("Form").Controls("SubForm").Requery DoCmd.GoToRecord acActiveDataObject, Forms("Form").Controls("SubForm"), acGoTo, i End Sub これをすると、実行時エラー2498 指定した式は、いずれかの引数とデータ型が対応していません。 になりますが、 どこがおかしいのでしょうか?

  • アクセス2007 フォームでフィルタ抽出した全フィールドの書き換え

    アクセス2007 フォームでフィルタ抽出した全フィールドの書き換え アクセスメニュー(リボン?)にある「フィルタの実行」で抽出されたデータがあるフォームです。 フィールドの値を一気に変更するスベを知らなく現在下記のようにしています。 For d = 1 To Me.Recordset.RecordCount    DoCmd.GoToRecord acDataForm, Me.Name, acGoTo, d    Me![目的のフィールド] = ”テスト” Next これでもできるのですが、いまいち納得しません。 もっと、スマートな方法はないですか? 抽出にはアクセスメニュー(リボン?)を使っています。

  • GoToRecord の使い方

    単票フォームにテーブル1のフィールド1が紐付いてテキストボックス(フィールド1)があり、 もう一つテキストボックス(txt移動用)を作り、 その値のレコードに移動するようにしたいのですが、 Private Sub txt移動用_AfterUpdate() DoCmd.GoToRecord acDataForm, Me, acGoTo, Me.txt移動用.Value End Sub とすると、 "実行時エラー2498 指定した式は、 いずれか の引数とデータ型が対応していません。” となってしまいます。 DoCmd.GoToRecord acDataForm, Me, acGoTo, CLng(Me.txt移動用.Value) にしても同じでした。 フィールド1には数値が入っていて、データ型も数値です。 どこを修正すればいいか教えてください。 (添付画像は、現在1レコード目で、2レコード目に移動しようとしているとこです)

  • accessからexcelへ出力時。。。

    3つのクエリを一つのエクセルシートへ出力しようとしているのですが、 3つ目が張り付きません。なんでなんでしょうか?どなたか教えてください。 Dim dbs As Database Dim rst1 As Recordset Dim rst2 As Recordset Dim rst3 As Recordset Dim intRow As Integer Dim intCell As Integer Dim xlsx As Object Set dbs = CurrentDb Set rst1 = dbs.OpenRecordset("クエリA") Set rst2 = dbs.OpenRecordset("クエリB") Set rst3 = dbs.OpenRecordset("クエリC") Set xlsx = CreateObject("Excel.Application") 'Excelオブジェクトを生成 With xlsx .ScreenUpdating = False '画面の再描画を抑止 .Workbooks.Add '新しいブックを追加 '---"クエリA"---------------------------------------------------- intRow = 1 For intCell = 1 To rst1.Fields.Count .Cells(intRow, intCell).Value = rst1.Fields(intCell - 1).Name .Cells(intRow, intCell).Interior.ColorIndex = 15 Next intCell '各レコード出力 intRow = 2 Do Until rst1.EOF For intCell = 1 To rst1.Fields.Count .Cells(intRow, intCell).Value = rst1.Fields(intCell - 1) Next intCell intRow = intRow + 1 rst1.MoveNext Loop '集計Sum For intCell = 4 To rst1.Fields.Count .Cells(intRow + 1, intCell) = "=SUM(" & Cells(2, intCell).Address & ":" & Cells(intRow, intCell).Address & ")" Next intCell ・ ・2目のクエリはOK ・ ・ ’以下3つ目のクエリ Dim intRow3 As Integer Dim intCell3 As Integer intRow3 = intRow + 5 intCell3 = 5 For intCell3 = 5 To rst3.Fields.Count .Cells(intRow3, intCell3).Value = rst3.Fields(intCell3 - 1).Name .Cells(intRow3, intCell3).Interior.ColorIndex = 15 Next intCell3 '各レコード出力 intRow3 = intRow + 6 Do Until rst3.EOF For intCell3 = 5 To rst3.Fields.Count .Cells(intRow3, intCell3).Value = rst3.Fields(intCell3 - 1) Next intCell3 intRow3 = intRow3 + 1 rst3.MoveNext Loop '---- Dim rst3RC As Integer rst3RC = intRow + 5 + rst3.RecordCount '863 '集計Sum For intCell3 = 6 To rst3.Fields.Count - 1 .Cells(rst3RC, intCell3) = "=SUM(" & Cells(rst3RC - rst3.RecordCount, intCell3).Address & ":" & Cells(rst3RC - 1, intCell3).Address & ")" Next intCell3

専門家に質問してみよう