こんにちわ
タイトルの件について、以下のようにコーディングしたのですが、保存が出来ません。何が原因なのでしょうか?
皆様、何卒ご教授ください。
一応、参照設定の MADO2.8 にはチェックしてます。
Public Sub DB_Open(DBName As String)
Set AdoDBType = New ADODB.Connection
With AdoDBType
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _
& DBName & ";Persist Security Info=False"
'DBNameにはc:\00管理\Access\管理.mdbが入ります。
.CommandTimeout = 10
.Open
End With
End Sub
===================================================
Public AdoDBType As ADODB.Connection '別のモジュールに記述してます。
===================================================
Public Sub DB_Data_Input(DbKey As Long)
Dim rv As Long
Dim i As Integer
Dim Scan As String
Dim MyTable As ADODB.Recordset
On Error GoTo ErrorMsg
Set MyTable = New ADODB.Recordset
Scan = "select * from [テーブル] WHERE [フィールド0]= " & DbKey & ""
'テーブルを設定
Call MyTable.Open(Scan, AdoDBType, adOpenDynamic, adLockOptimistic)
' 見つかれば
If MyTable.EOF = True Then
MyTable.AddNew
MyTable!フィールド0 = ID
End If
With frmT
MyTable("フィールド1") = IIf(frmT.txtT(0) <> "", frmT.txtT(0), "")
MyTable("フィールド2") = IIf(frmT.txtT(1) <> "", frmT.txtT(1), "")
End With
MyTable.Update
MyTable.Close
Set MyTable = Nothing
Exit Sub
ErrorMsg:
MsgBox Err.Description, vbCritical Or vbSystemModal
Exit Sub
End Sub
保存できない、とのことですが具体的にはどういうことでしょう?
エラーが発生して処理が完結しないのか、処理が完結してるのに更新されないのか。
新規追加が出来ないのか、既存のデータの更新が出来ないのか、などなど。
あんまり関係ないかもしれませんが、気になった点を少々。
>' 見つかれば
> If MyTable.EOF = True Then
> MyTable.AddNew
> MyTable!フィールド0 = ID
> End If
変数IDが突然出てきてますが、どこかで指定されている物なのでしょうか?
私が見る限り、DbKeyを入れるべきかと思いますが。
> With frmT
> MyTable("フィールド1") = IIf(frmT.txtT(0) <> "", frmT.txtT(0), "")
> MyTable("フィールド2") = IIf(frmT.txtT(1) <> "", frmT.txtT(1), "")
> End With
Withステートメント内なのでfrmTを指定する必要はないですね。
てゆーか、このIIf関数自体不要かと思いますが……。
With frmT
MyTable("フィールド1").Value = .txtT(0).Text
MyTable("フィールド2").Value = .txtT(1).Text
End With
nanashiさんレスありがとうございます。
まず
>保存できない、とのことですが具体的にはどういうことでしょう?
すみません。記述不足でした。
特にエラーメッセージは出ません。
保存できない内容として、新規追加もデータの更新も出来ません。
新規追加の場合、新しくレコードを作成するようにしているのですが、レコードも作成されません。
例え、該当するレコードがあっても(レコードの更新)更新内容が保存されません
>変数IDが突然出てきてますが、どこかで指定されている物なのでしょうか?
>私が見る限り、DbKeyを入れるべきかと思いますが。
これも、記述不測でした
DbKey=IDです。
>Withステートメント内なのでfrmTを指定する必要はないですね。
>てゆーか、このIIf関数自体不要かと思いますが……。
そうですね。(^^ゞ
よろしくお願いします。
> 保存できない内容として、新規追加もデータの更新も出来ません。
処理的には大きなミスは無いような気がしますので、
・Option Explicitが宣言されているか、確認してください。(スペルミスの予防)
・Jet 4.0 Service Pack 8が適用済みか、確認してください。(環境による問題の軽減)
・「エラー発生時に中断」の設定で実行してみてください。(On Errorでスキップされる事を回避)
・他のmdb——例えばVB付属のNWIND.MDBなど——でも同じ現象が起きますか? (mdb破損の可能性)
といった所を確認してみてください。
で、以下細かい突っ込みを。
> Call MyTable.Open(Scan, AdoDBType, adOpenDynamic, adLockOptimistic)
Jetプロバイダは、動的カーソル(adOpenDynamic)をサポートしていません。
替わりに、
サーバ側カーソル(adUseServer)の時は、キーセットカーソル(adOpenKeyset)
クライアント側カーソル(adUseClient)の時は、静的カーソル(adOpenStatic)
を指定するようにして下さい。
> MyTable!フィールド0 = ID
> MyTable("フィールド1") = IIf(frmT.txtT(0) <> "", frmT.txtT(0), "")
前者はコレクションによる列参照、後者はプロパティによる参照ですね。
その場その場で記法を変えたりせず、いずれかに統一させた方が良いですよ。
なお、速度的な面から言えば、
MyTable.Fields("フィールド0").Value = frmT.txtT(0).Text
のように、FieldsプロパティとValueプロパティを明示した方が
高速となります。(TextBoxのTextプロパティも、省略しない方が望ましいです)
もしくは、Field.Valueの替わりにCollectプロパティを使って
MyTable.Collect("フィールド0") = frmT.txtT(0).Text
でもOKです。
この点に関しては、下記が一つの指針になると思います。
http://www.gj.il24.net/~nakasima/vb/tech/style/
http://www.fukkey.dyndns.org/pins/vb/010814/29262.html
http://www.ocv.ne.jp/~oratorio/junk/draft/VBML_FAQ-Project/vb-free.044761.html
魔界の仮面弁士さん、レスありがとうございます。
>Option Explicitが宣言されているか、確認してください。(スペルミスの予防)
一応、関係するモジュールは宣言していました。
>Jet 4.0 Service Pack 8が適用済みか、確認してください。(環境による問題の軽減)
適用済みか、の確認はしていませんが、SP8をMSのHPよりダウンロードして適用しました。但し、適切に適用されているか確認していません。(確認方法がわからない)
>「エラー発生時に中断」の設定で実行してみてください。(On Errorでスキップされる事を回避)
設定してみましたが、特に変化は無く、問題は解決されないままプログラム実行は完了しました。
>他のmdb——例えばVB付属のNWIND.MDBなど——でも同じ現象が起きますか? (mdb破損の可能性)
新しく同じテーブル、同じフィールドを新規mdbを作成して試しましたが、結果は同じでした。
又、
>サーバ側カーソル(adUseServer)の時は、キーセットカーソル(adOpenKeyset)
>クライアント側カーソル(adUseClient)の時は、静的カーソル(adOpenStatic)を指定するようにして下さい。
両者とも試しましたが同じ結果でした。
FieldsプロパティとValueプロパティの利用に関してご教授くださいましてありがとうございます。とても勉強になりました。(^^)
本題の件で気になるのは、【プロジェクト→参照設定】で以下のものがチェックしているのですが、問題は無いのでしょうか?
Visual Basic For Applications
Visual Basic runtime objects and procedures
Visual Basic objects and procedures
OLE Automation
Microsoft Data Binding collection VB 6.0(SP4)
Microsoft Excel 9.0 Object Library
Microsoft Access 9.0 Object Library
Microsoft Data Source Interfaces
Microsoft Jet and Replication objects 2.6 Library
Microsoft ADO Ext.2.8 for DDL and Security
Microsoft ActiveX Data Objects 2.8 Library
Microsoft DAO 3.6 Object Library
Microsoft Data Access Components Installed Version
Microsoft OLE DB Service Component 1.0 Type Library
では、以下を実行するとどうなりますか?
'これから指定する値を表示
Debug.Print "New Value = "; DbKey
'元の値を表示
Debug.Print "Old Value = "; MyTable.Fields("フィールド1").Value
'データを格納
MyTable.Fields("フィールド1").Value = DbKey
'データが格納されたかどうかを確認
Debug.Print MyTable.Fields("フィールド1").Value = DbKey
'格納したデータをDBに反映
MyTable.Update
'Update後も、同じデータが表示されるか確認
Debug.Print MyTable.Fields("フィールド1").Value = DbKey
------------
データが正しく編集される場合、イミディエイト ウィンドウに
New Value = (新たな値)
Old Value = (元の値)
True
True
と表示されると思います。
もし、ここまでは正しく処理されているのであれば、
CommitTransメソッドを呼び出すのを忘れていないかも
確認してみてください。
> 以下のものがチェックしているのですが
特に理由が無ければ、不要な物は外した方が良いですよ。
nanashiさん、魔界の仮面弁士さん ご教授、誠にありがとうございました。
特に魔界の仮面弁士さんには最後までお付き合いくださいましたことを心から感謝しております。
おかげ様で解決することが出来ました。(^^ゞ
原因は、魔界の仮面弁士さんのご指摘通り、CommitTransメソッドを呼び出すことをしていませんでした。
対処方法としては、CommitTransメソッドを MyTable.Update の後に追加しました。
また、何かありましたらよろしくお願い致します。