VB初心者のためのAccessデータ更新方法

このQ&Aのポイント
  • VB初心者でも簡単にAccessのデータを更新する方法を解説します。
  • 抽出条件からAccessのデータを取得し、レコードの一項目を更新する手順を説明します。
  • VB6でAccess2003を使用していますが、更新処理がうまくいかない場合の対処方法も紹介します。
回答を見る
  • ベストアンサー

VB初心者ですAccessを更新したいのですが

VB初心者です、よろしくお願いします。 VBでAccessのレコードの一項目を更新したいのですが出来ません。 抽出条件からAccessのデータを持ってきた後、更新したいのですがどうすればいいのでしょうか? 因みに抽出条件までは変更できません、AddNew以降でお願いします。 VB6でAccess2003です。 エラーは現在のRecordsetは更新をサポートしておりませ。プロダイバーかロックタイプの限界の可能性があります。 Set rst = New ADODB.Recordset '処理をするテーブル指定 rst.Open "[**]", db, adOpenStatic, adLockOptimistic With rst .MoveFirst .Filter = "" criteria1 = "" criteria1 = "**= '" & Module1.** & "'" .Filter = criteria1 If .RecordCount = 0 Then MsgBox "は登録されていません" Else .Filter = "" criteria2 = "" criteria2 = "**= '" & Module1.** & "' " .Filter = criteria2 If .RecordCount = 0 Then MsgBox "登録されていません" Else .Filter = "" criteria3 = "" criteria3 = "**'" & Module1.** & "' " .Filter = criteria2 If .RecordCount = 0 Then MsgBox "登録されていません" Else Module1.** = rst.Fields("**") .AddNew .Fields("***") = Module1.** .Update End If End If End If End With

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

  • ベストアンサー
  • ese_ee
  • ベストアンサー率48% (68/139)
回答No.1

プロバイダやCursorLocationによっては、 指定したCursorType、LockTypeが違うものに置き換えられている場合 があります。 また、クエリが更新可能であることを確認してください。 プライマリキーを持たないODBCテーブルリンクが結合に含まれている等で更新できない場合があります。 例えば、今回Recordsetに渡したSQL文と同一のクエリーをAccessで作成し、 これが更新できるかどうか...等で確認できると思います。 抽出条件が変えられないのであれば、 単一のテーブルごとにUPDATE文を発行する等(トランザクションを使用する等で整合性は確保してください)、 更新方法を変えることを検討してみてください。

minagawa88
質問者

お礼

ありがとうございます、大変参考になりました。やはり更新方法を変更せざるを得ませんね、思い切って聞いてみてよかったです。

関連するQ&A

  • データベースから複数の条件を指定して抽出するには

    VB初心者です。よろしくお願いします。 今、座席予約システムを作っています。その際、複数の条件を指定して、その条件に合うIDを抽出しようとしていますが、うまくいきません。具体的には、テーブル:[T-映画]の中にある、フィールド:[映画名]とフィールド:[時間帯]がそれぞれ一致したときに、同じテーブルにあるフィールド[映画ID]のデータを抽出するという処理です。 コードは次の通りです。 Private Sub Command1_Click() Dim db As ADODB.Connection Dim rst3 As ADODB.Recordset Set db = New ADODB.Connection db.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source =データベースへのパス\zaseki.mdb" db.Open Set rst3 = New ADODB.Recordset rst3.Open "[T_映画]", db, adOpenKeyset, adLockReadOnly With rst3 .Filter = "映画名= ' " & Module1.mojiB & " ' " ☆☆ If .RecordCount = 0 Then MsgBox "その映画は登録されていません" Else rst3.Filter = "時間帯 =' " & Module1.mojiC & " ' " If rst3.RecordCount = 0 Then MsgBox "その映画は登録されていません" Else Module1.eigaID = rst3.Fields("映画ID") End If End If End With rst3.Close db.Close Set db = Nothing Set rst3 = Nothing End Sub ☆☆の部分で映画名があるにも関わらずカウントしてくれません。 変数Module1.mojiB には、String型の映画名が Module1.mojiC には、String型の時間帯がそれぞれ入っています。 フィールド[映画名]、[時間帯]の型はテキスト型です。 よろしくお願いします。

  • ExcelからAccess2013DBを更新する時

    Excel2013 vba-> Access2013 mdbファイル 問題点:以下のソースを実行すると、エラーが発生します。このエラーをなくしてアクセスデータベースのテーブルの情報の更新、新規追加、削除を行いたいです。 エラー内容:実行時エラー'3251' 現在のRecordsetは更新をサポートしていません。プロバイダーか、選択されたロックタイプの限界の可能性があります。 ソース: Sub 登録処理()   Dim Rst As adodb.Recordset   Dim SQL As String   Dim Rg As Range   Dim RgData As Range   Dim lngLastRow As Long   Dim RgDel As Range      On Error GoTo errH      Set RgData = mySh.Range("B2")   lngLastRow = RgData.End(xlDown).Row   Set RgData = mySh.Range(RgData, mySh.Range("AB" & lngLastRow))      SQL = "Select * from [会社管理テーブル]"   Call DBconection2   Set Rst = New adodb.Recordset   With Rst     .ActiveConnection = Cn     'SQL文でテーブル名と抽出条件を指定する     .Source = SQL     .CursorLocation = 3 ' クライアントサイドカーソルに変更     .Open        End With      Dim y As Long      Sheets("会社管理").Select      If Rst.EOF = False And Rst.BOF = False Then          For i = 1 To RgData.Rows.Count              If Cells(i + 1, 1).Value = "変更" Then         Rst.MoveFirst         Rst.Find "[施工会社ID]=" & RgData(i, 1).Value         If Rst.EOF Then                    Else           Rst.Fields("会社ID").Value = RgData(i, 2).Value           Rst.Fields("会社名").Value = RgData(i, 3).Value           Rst.Fields("フリガナ").Value = RgData(i, 4).Value              Rst.Update         End If         Cells(i + 1, 1).Value = ""       ElseIf Range(i, 1).Value = "削除" Then         Rst.MoveFirst                  Rst.Find "[会社ID]=" & RgData.Cells(i, 1).Value         If Rst.EOF Then                    Else           Rst.Delete         End If         Set RgDel = Rows(i + 1 & ":" & i + 1)         RgDel.Select         RgDel.Delete                ElseIf Range(i, 1).Value = "新規" Then         Rst.AddNew         Rst.Fields("会社ID").Value = RgData(i, 2).Value         Rst.Fields("会社名").Value = RgData(i, 3).Value         Rst.Fields("フリガナ").Value = RgData(i, 4).Value         Rst.Update         Cells(i + 1, 1).Value = ""       End If            Next i        End If exitH:      Rst.Close: Set Rst = Nothing   Call DBclose2   Exit Sub         errH:   MsgBox Err.Number & "(" & Err.Description & ")"   GoTo exitH    End Sub Sub DBconection2()   Set Cn = New adodb.Connection   Cn.Provider = "Microsoft.Jet.OLEDB.4.0"   Cn.Open modPublic.DBPATH    End Sub Function MakeDBconection() As adodb.Connection   Set Cn = New adodb.Connection   Cn.Provider = "Microsoft.Jet.OLEDB.4.0"   Cn.Open modPublic.DBPATH      Set MakeDBconection = Cn    End Function Sub DBclose2()   Cn.Close   Set Cn = Nothing End Sub Sub EraseContents(s_Rg As Range)   s_Rg.ClearContents    End Sub 誰か、解決方法がおわかりの方がいましたら、アドバイスをよろしくお願いします。

  • ACCESSへの更新に関して

    以下のような記述をして、VBからACCESSのテーブルに書き込みを行おうとしています。 その際に、開発をしているVisual Basic2008のデバックモードでは、問題なくACCESSに 更新ができますが、コンパイルしてできあがった"EXE"から実行した場合、ACCESSへの更新ができません。 エラーが起こっているかと思い、updateのあるfor文にポップアップを出すような仕掛けを作り、試してみましが、 そこを通過するものの、エラーも何も起こらずに正常終了してしまいます。 何が原因でしょうか。。。教えて下さい。 環境  Windows7/ACCESS2000/VB2008/参照設定:Microsoft ActiveX Data Objects 2.8 Library   'データベースファイル名 Dim dname As String = "C:\test.mdb" 'データベースパラメータ Dim strDatbasePara As String Dim Cnn As New ADODB.Connection Dim Rst As New ADODB.Recordset strDatbasePara = "Provider=Microsoft.Jet.OLEDB.4.0;" + _ "Data Source=" + dname + ";" + _ "Jet OLEDB:Engine Type=5;" Try Cnn.Open(strDatbasePara) Rst.Open("table", Cnn, ADODB.CursorTypeEnum.adOpenDynamic, ADODB.LockTypeEnum.adLockOptimistic) If Rst.EOF Then For jcount = 0 To icount - 1 Rst.AddNew() Rst.Fields("項目1").Value = "AAA" Rst.Update() Next End If Rst.Close() Catch ex As Exception smsg = "失敗しました。" MessageBox.Show(smsg, "更新", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) End Try Cnn = Nothing Rst = Nothing

  • ACCESS2000でコードごとの連番を振るには

    規約違反で削除されましたので再質問させていただきます。 ・access2000で部門コードごとに連番を振りたいが、その際「単価」が入力されていないものは省きたい。 アドバイスを受けて以下のコードを作りましたが、連番を付与したあとで単価を削除しても連番が消えません。その次の数値と同じ連番が入ったままになっています。 文字数の関係で関係のありそうな後半だけしか書くことができませんが、よろしくお願いします。 Set dbs = CurrentDb Set rst = dbs.OpenRecordset(sql) Set fldCode = rst.Fields("部門コード") Set fldNo = rst.Fields("番号") If rst.BOF = False Then rst.MoveLast rst.MoveFirst count = 1 code = "00" Do Until rst.EOF rst.Edit If fldCode <> code Then Select Case fldCode Case "01": count = 21 Case "02": count = 31 Case Else: count = 1 End Select code = fldCode End If If rst.Fields("単価") > 0 Then fldNo = count rst.Update count = count + 1 End If rst.MoveNext Loop End If dbs.Close cmd連番_Click_Err_Exit: Exit Sub cmd連番_Click_Err: MsgBox Error$ Resume cmd連番_Click_Err_Exit End Sub

  • Access 非連結からレコード追加について

    標記の件。 不明な点がありご教授頂きたくお願い致します。 今まで普通に使えていたのですが急にエラー「実行時エラー2147467259・(80004005)エラーを特定できません」が出るようになりました。 Windowsのヘルプを参照しましたが、全然ヘルプどころか謎が深まるばかりという状況です。 2つあるチェックボックスの2つ目でエラーになります。 下記コードで全体の改善点含め原因等ありましたらご教授をお願い致します。クエリに変更はありませんでした。 Private Sub btn_登録_Click() Dim con As ADODB.Connection Dim rst As ADODB.Recordset Set con = CurrentProject.Connection Set rst = New ADODB.Recordset If IsNull(txt_工数ロットCD = "" Or _ txt_部品CD = "" Or _ txt_図面番号 = "" Or _ txt_数量 = "" Or _ txt_品名 = "" Or _ cmb_社員名 = "" Or _ txt_作業日 = "" Or _ cmb_工程 = "" Or _ txt_工数 = "") Then MsgBox " 未入力項目があります", vbCritical, "確認" Exit Sub End If If txt_工数ロットCD = "" Or _ txt_部品CD = "" Or _ txt_図面番号 = "" Or _ txt_数量 = "" Or _ txt_品名 = "" Or _ cmb_社員名 = "" Or _ txt_作業日 = "" Or _ cmb_工程 = "" Or _ txt_工数 = "" Then MsgBox "未入力項目が有ります", vbCritical, "確認" Exit Sub End If rst.Open "Q_工程進捗確認", con, adOpenForwardOnly, adLockPessimistic On Error GoTo err_handler 'エラーなら con.BeginTrans ' With rst .AddNew .Fields("工数ロットCD") = Me!txt_工数ロットCD .Fields("部品CD") = Me!txt_部品CD .Fields("数量") = Me!txt_数量 .Fields("社員名") = Me!cmb_社員名 .Fields("作業日") = Me!txt_作業日 .Fields("工程") = Me!cmb_工程 .Fields("工数") = Me!txt_工数 If IsNull(Me.chk_自工程完了) Then .Update Else .Fields("自工程完了") = Me.chk_自工程完了 .Update '更新 End If If IsNull(Me.chk_製作完了) Then .Update '更新 Else .Fields("製作完了") = Me.chk_製作完了.Value ←ここでエラー .Update End If End With con.CommitTrans '確定 Set rst = Nothing Set con = Nothing Call btn_クリア_Click Exit Sub err_handler: con.RollbackTrans Call dbcut_off MsgBox Error$ Debug.Print Error$ End Sub

  • アクセスのフォームからレコード入力空欄回避のVBA

    アクセス初心者です。 帳票式フォームからテーブルへのレコード入力において、次のレコード入力ボタンで空欄を防止するためのVBAを作っていますが、うまく行きません。空欄があれば警告は出ますがそのままテーブルへ記録されてしまいます。 テーブルに記録されずに空欄が入力できるようにするにはどうすればよいのでしょうか? また、次を入力するときにフォームの製品名の内容だけ消えずに残したいのですが、そのプログラムについても教えていただきたいです。 なかなかうまく行かずに大変困っています。 どなたかVBAの達人の方、初心者にわかりやすくお教え下さい。 「入力内容を登録して次を入力」ボタンで作ったVBAは次の通りです。 つぎはぎなので、不要なプログラムもあるかもしれません。 Private Sub コマンド9次のレコードに_Click() On Error GoTo Err_コマンド9次のレコードに_Click DoCmd.GoToRecord , , acNext Exit_コマンド9次のレコードに_Click: Exit Sub Dim Rst As DAO.Recordset Set Rst = CurrentDb.OpenRecordset("T_指定材料表", dbOpenTable) With Rst .AddNew .Fields("製品名") = Me!製品名 .Fields("回路記号") = Me!回路記号 .Fields("部品名") = Me!部品名 .Fields("員数") = Me!員数 .Update If IsNull(Me!製品名) Then MsgBox ("製品名が空欄です。") Resume Exit_コマンド9次のレコードに_Click End If If IsNull(Me!回路記号) Then MsgBox ("回路記号が空欄です。") Resume Exit_コマンド9次のレコードに_Click End If If IsNull(Me!部品名) Then MsgBox ("部品名が空欄です。") Resume Exit_コマンド9次のレコードに_Click End If If IsNull(Me!員数) Then MsgBox ("員数が空欄です。") Resume Exit_コマンド9次のレコードに_Click End If End With On Error Resume Next DoCmd.GoToRecord DataForm, "T_指定材料表", acNew Rst.Close Set Rst = Nothing Call ClearControls End Sub

  • VB2005でAddNew()

    VB2005Express、SQLServer2005にて開発を行っています。 テーブルに対してSELECTを行った結果、該当レコードがなかったらAddNewでレコードを追加しようと実行すると 「現在のRecordsetは更新をサポートしていません。プロバイダか選択されたロックタイプの限界の可能性があります。」 というエラーが発生します。 レコードセットのパラメータを色々変えてみたのですが状況が変わりません。どなたか原因がお分かりの方いらっしゃいましたら教えて下さい。 Dim cn As New ADODB.Connection Dim rs As New ADODB.Recordset strCn = "Provider=WWW;Password=XXX;User ID=YYY;Data Source=ZZZ;Persist Security Info=True" cn.Open(strCn) cn.BeginTrans() Try strSQL = "SELECT * FROM テーブル1"   rs.Open(strSQL, cnGSTAFF, ADODB.CursorTypeEnum.adOpenDynamic, ADODB.LockTypeEnum.adLockOptimistic) If rs.EOF Then '登録 rs.AddNew() rs.Fields("コード").Value = 10000 rs.Fields("内容").Value = "OK" Else '更新処理 End If rs.Update() rs.Close() cn.CommitTrans() cn.Close() Catch ex As Exception rs.Close() cn.RollbackTrans() End Try

  • VBA null判定

    Accessでテキストボックスの値をテーブルへ書き込むVBAを作成しているのですが、Null判定がうまくいきません。 ◎環境 OS:Windows7Pro Var:Access2010 DB:MySQL5.6 Private Sub cmdSubmit_Click() Dim Rst As DAO.Recordset Dim ErrT As String Set Rst = CurrentDb.OpenRecordset("m_plan", dbOpenDynaset) '各テキストボックス、Null判定 If IsNull(txtPid) Then MsgBox "プランID[" & txtPid & "]が未入力です" Call txtCrer Exit Sub End If If IsNull(txtPName) Then MsgBox "プラン名が未入力です" Call txtCrer Exit Sub End If If IsNull(txtPsdate) Then Me!txtPsdate = #01/01/2010# End If If IsNull(Me!txtPedate) Then Me!txtPedate = #01/01/2010# End If Debug.Print "プランID["; Me.txtPid & "]" Debug.Print "プラン名[" & Me!txtPName & "]" Debug.Print "開始日[" & Me!txtPsdate & "]" Debug.Print "終了日[" & Me!txtPedate & "]" ↑↑↑↑↑↑↑↑↑ ここで、Null判定を行ってますが、データがあるにも関わらず、処理が続行されたり、Null判定結果が起動するたびに変わります。 On Error GoTo err With Rst .MoveLast .AddNew .Fields("PlanID") = Me!txtPid .Fields("PlanName") = Me!txtPName .Fields("PlanSt") = CDate(Me!txtPsdate) .Fields("PlanEn") = CDate(Me!txtPedate) .Fields("P_Remaks") = Me!txtPbikou .Update End With Rst.Close Set Rst = Nothing err: MsgBox "DBエラー" Debug.Print Rst.Type Debug.Print err.Description Call txtCrer End Sub ただし、下記判定だけのボタンとプロシージャーでは、正常に判定されます。 判定だけの、プロシージャー 'Null判定テスト Private Sub cmdtest_Click() If IsNull(txtPid) Then Debug.Print "[" & txtPid & "]" & "Nullです。" Else Debug.Print "[" & txtPid & "]" & "Not Nullです。" End If If IsNull(txtPName) Then Debug.Print "[" & txtPName & "]" & "Nullです。" Else Debug.Print "[" & txtPName & "]" & "Not Nullです。" End If If IsNull(txtPsdate) Then Debug.Print "[" & txtPsdate & "]" & "Nullです。" Else Debug.Print "[" & txtPsdate & "]" & "Not Nullです。" End If Debug.Print "===============================" End Sub どこが間違っているかまったくわかりません、アドバイスを頂けましたら幸いです。

  • yymmddを用いた管理番号のエラーについて

    以前、こちらでfuuten_no_nekoさまに大変お世話になったものです。 以前のIDがわからなくなり、再登録しました。 まえに、helpaccessのIDで質問させていただいた件について、困ったことが出てきたので、 再度、こちらでお助けいただければと思い質問させていただきました。 以前、こちらで教えていただき、Accessで、管理番号追加というボタンを作成し、そのボタンを押すと、 yymmddプラス2ケタの通し番号が自動的に払いだされるようにしておりました。 たとえば、今日が 2009年12月25日なら、09122501から順に、09122502、09122503とボタンをクリックする度に払い だされるようになっておりました。 ただ、2010年に変わったとたん、たとえば、今日が2010年1月5日なら、一度目のクリックでは、 10010501と払いだされるのですが、2度目のクリックで桁数が増え、010010502と、最初に0が ついてしまい、実行時エラー3022となります。 デバックをクリックすると、下記VBAの←部分が黄色く反転しています。 rst.Fields("管理番号").Value = MngNo rst.Fields("刃具ID").Value = 刃具ID rst.Fields("顧客ID").Value = 顧客ID rst.Fields("登録日").Value = Date rst.Update   ←←←←←←←←←←←←←<この部分が黄色く反転している> 2010年になったことが原因なのでしょうか。 恐れ入りますが、従来通り、8ケタで表示できる方法がおわかりであればどなたかどうぞ教えてくださいませ。 なにとぞ、よろしくお願い申し上げます。 管理番号追加ボタンのVBA ******************************************************************************************** Private Sub コマンド16_Click() Dim dbs As Database Dim stDocName As String Dim rst As DAO.Recordset Dim 刃具ID As Integer Dim 顧客ID As Integer Set rst = Me.Recordset If rst.RecordCount > 0 Then rst.MoveLast End If 刃具ID = Form_管理番号フォーム.刃具ID 顧客ID = Form_管理番号フォーム.顧客ID If rst.Fields("登録日").Value = Date Then MngNo = rst.Fields("管理番号").Value + 1 MngNo = "0" & MngNo Else MngNo = Format(Date, "yymmdd") & "01" End If Set dbs = CurrentDb Set rst = dbs.OpenRecordset("管理番号テーブル") rst.AddNew rst.Fields("管理番号").Value = MngNo rst.Fields("刃具ID").Value = 刃具ID rst.Fields("顧客ID").Value = 顧客ID rst.Fields("登録日").Value = Date rst.Update On Error GoTo errorhandler16 Set rst = Me.Recordset With rst .Requery .MoveLast .MovePrevious .MovePrevious .MovePrevious .MovePrevious End With errorhandler16: MsgBox "管理Noを追加しました!" & Chr(13) _ & "「顧客名」を確認のうえ、「再研磨記録フォーム」にて" & Chr(13) _ & "受付日の登録手続きをしてください。", vbOKOnly + vbInformation, "メッセージ" Me.Requery End Sub ********************************************************************************************

  • 異なるフォームに属する関数間でACCESSのレコードセットを受け渡しする。

    msAccess2000のVBAコードの質問です。 元々、全てを理解しているわけではないのにVBAコードを書いているのが無茶なんですが、無茶を承知でプログラミングしています。 あるクエリの結果を、あるフォームで帳票表示しています。この帳票の一レコードにボタンをつけて、クリックイベントで、そのレコードを取得しようとしています。フォームはこの後、閉じられた後、呼び出された親にその、レコードを渡したいのです。 フォームは、親フォームのボタンクリックイベントから、DoCmd.Openformメソッドによって呼び出されるので、戻り値は使えません。 しょうがないので、広域変数rst(DAO.Recordset型)で、受け渡そうと思ったのですが、recordset型は、どうやら参照のようで、フォーム(クエリ?)を閉じると、レコードが壊れてしまうようなのです。 Module1で、 public rst as DAO.recordset として、 Private Sub コマンド34_Click() set Module1.rst=me.recordset ' この中では、rst.fields(*)で、フィールドの値を使えるのですが・・・ END Sub 呼び出した親フォームでは、module1.rst.fields(*)を使用できません。 質問は二つあります。 1)広域変数rstは、上記のような宣言・使用法で問題ないですか? 2)sub またはfunction間にわたって、レコードを渡す、いい方法はないですか?

専門家に質問してみよう